Мы используем API, который в значительной степени полагается на исключения для возврата не исключительных результатов. Примером этого (из многих) является то, что для выяснения того, находится ли пользователь в группе людей, мы должны попытаться получить группу и интерпретировать результирующее исключение "без группы". Кроме того, все эти исключения относятся к одному типу.
Мы работаем над большим и сложным проектом с использованием С++ 11, который сильно многопоточен, кроме того, область, над которой мы работаем, связана с сетевой связью, поэтому в точках мы должны одновременно отлаживать несколько экземпляров.
Наша проблема и, следовательно, основание моего вопроса возникает из-за влияния исключительных исключений на наш рабочий процесс. Мы сдержанны, чтобы отключить отчет об исключительных исключениях для единого исключения, который вызывается API, потому что это будет означать, что если у нас есть вызов API, для которого кодер пропустил блок try/catch, мы разберемся для основного и освобождения контекста вызова. Если оставить исключения, тогда простое не исключительное поведение, например, описанное в приведенном выше примере, может привести к множественным разрывам (исходный бросок и потенциально некоторые повторения), и мы можем только убедиться, что это фактически не- исключительное исключение, запрашивая стек, часто не основной поток, чтобы найти вызов API, который ускорил исключение.
Я считаю, что наш прецедент не настолько уникален, что другие не будут испытывать те же проблемы с рабочим процессом, и поэтому мой вопрос заключается в том, как мы должны изменить наш процесс отладки, чтобы лучше справляться с проблемами, возникающими из-за исключительных исключений, как описано выше,
В настоящее время мы ограничены использованием Visual Studio (или потенциально WinDbg) для отладки.
Выбрасывание исключений в неисключительном случае использования просто неверно. Следующий шаг: каждая функция void
, все возвращается, бросая исключения.
Насколько я понимаю, вы используете API третьей стороны, который показывает это странное поведение. Вот что я обычно рассматриваю при работе с "Odd API" любого типа, включая C-API, которые загрязняют все с помощью глупых макросов (да, я смотрю на вас, WinAPI):
if(hasGroup) getGroup; else...
if(hasGroup) getGroup; else...
вместо try {getGroup;} catch(X) {...}
Вместо того, чтобы позволить нечетности пульсировать по всему вашему коду, ограничьте его, написав API-интерфейс обертки. В вашем случае: напишите обертку, которая ловит Исключения и переводит их в нормальные значения возврата. Таким образом, ваши кодеры не могут забыть перехватывать обычные исключения (потому что ваша обертка не бросает их), и если вы поместите оболочку в свою собственную библиотеку, вы можете использовать другую политику исключений внутри API-интерфейса обертки. Быстрый пример для вашей проблемы getGroup:
//myAPIWrapper.h
namespace myAPIWrapper {
class Group;
class User {
public:
boost::optional<Group> getGroup();
};
}
//myAPIWrapper.cpp
#include "OddAPI.h"
namespace myAPIWrapper {
boost::optional<Group> User::getGroup()
{
boost::optional<Group> theGroup;
try {
oddAPI::user& oddUser= unwrap(*this);
oddAPI::group& oddGroup = oddUser.get_group();
theGroup = wrap(oddGroup);
}
catch(oddAPI::exception&) {
}
return theGroup;
}
}