Всем привет
делаю некий модуль которому надо как то сообщать об ошибках хочется следующее
например ошибка модуля (логическая или еще какая но своя) просто кинуть код
а как это правильно сделать ?
вообще как в такой ситуации правильно обработку ошибок сделать ?
какие ограничения: использовать можно весь C рантайм из msvcrt.dll она линкуется как внешняя библиотека
кроме msvcpXX.dll статически ее слинковать тоже нельзя ибо размер прог с компонентом должен быть небольшой
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет J>делаю некий модуль которому надо как то сообщать об ошибках хочется следующее J>например ошибка модуля (логическая или еще какая но своя) просто кинуть код J>... J>а как это правильно сделать ?
А что, сделать по классу исключений на каждый тип ошибки нельзя?
Здравствуйте, ST1, Вы писали:
ST1>>>Использование универсально для любого msg типа char * V>>Какой бесконечный ужас и кошмар...
ST1>о std::string такого же мнения?
Разумеется. У разных исключений должны быть разные типы.
Здравствуйте, ST1, Вы писали:
ST1>Ребят, не ленитесь пройти по ссылке и изучить стоящий код, а мой пример лишь иллюстрация возможного использования.
Чтобы не писал этот неизвестный человек, но твой подход с макросами это не С++, а С. Фактически ты пишешь в лог место возникновения ошибки и делаешь return. Это очень напоминает С подход с goto когда есть требование одного входа/выхода из функции. Ты даже не пытаешься обработать ошибку, просто логируешь. Советую прочитать "Совершенный Код" Макконнела галву про исключения и про ошибки.
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет J>делаю некий модуль которому надо как то сообщать об ошибках хочется следующее J>например ошибка модуля (логическая или еще какая но своя) просто кинуть код
J>а как это правильно сделать ?
не понятно что тебе надо логировать ошибку или её обрабатывать? Исключения придуманы как гибкий механизм обработки ошибок, а не логировая. Если ты их просто логируешь, то это надо делать в месте возникновения ошибки. Если ошибка должна быть обработана заведи класс для каждого типа ошибок и отнаследуй от std::exception. То, что ты делаешь похоже на попытку избежать множества if(error) {print(error); return error;}, а не для нормального уведомления пользователя об ошибках.
K>Чтобы не писал этот неизвестный человек, но твой подход с макросами это не С++, а С. Фактически ты пишешь в лог место возникновения ошибки и делаешь return. Это очень напоминает С подход с goto когда есть требование одного входа/выхода из функции. Ты даже не пытаешься обработать ошибку, просто логируешь. Советую прочитать "Совершенный Код" Макконнела галву про исключения и про ошибки.
Угу, вот это
try {
...
} CATCH_THROW("Poisson test failed")
дает развернутое описание ошибки, что для дебага самое то:
ERROR: CException [d:\sources\joober\tests\main.cpp:61]: Poisson test failed
CException [d:\sources\joober\poisson\poisson_test.h:38]: Newton failed
CException [d:\sources\cpplib\math\numrecipies\linearsolvers.h:139]: Singular ma
trix in routine ludcmp
Это не обработка по вашему? Да фик с макросами моими, там в коде можно отнаследовать свои типы, все описано, кому надо разберется.
подробности ошибки в модуле будут исходить из трех источников
это winapi потом функции wininet.dll и третий HRESULT
сейчас при возникновении winapi ошибки или winhttp
можно бросить так
code = call_winhttp_or_winapi_api
if (success != code)
throw excpt();
или после HRESULT так
hr = call_ole_api
if (success != hr)
{
SetLastError(hr);
throw excpt();
}
ловятся все так если надо просто показать сообщение и прибить но в исключении еще код ошибки хранится на случай специальной обработки
catch (excpt &e)
{
FatalAppExit(0, e.szMsg);
}
вот реализация но чувствую что это адовый велосипед
template<class chType>
class GetWin32ErrorEx
{
enum{cchSize = 256};
chType _tszBuf[cchSize];
DWORD dwError;
public:
GetWin32ErrorEx(DWORD dwLastError = -1)
{
if (dwLastError != -1)
{
this->dwError = dwLastError;
}
else
{
this->dwError = GetLastError();
}
}
operator chType * ()
{
return select(chType());
}
private:
wchar_t * select(wchar_t)
{
return resolve(_tszBuf);
}
char * select(char)
{
wchar_t wszBuf[cchSize];
resolve(wszBuf);
wnsprintfA(_tszBuf, _countof(_tszBuf), "%S", wszBuf);
return _tszBuf;
}
template<size_t cchSize>
wchar_t * resolve(wchar_t (&wszBuf)[cchSize])
{
DWORD dwLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL bOk = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwError, dwLocale,
wszBuf, _countof(wszBuf), NULL);
if (!bOk)
{
HMODULE hDll = LoadLibraryExW(L"netmsg.dll", NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll)
{
bOk = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwError, dwLocale,
wszBuf, _countof(wszBuf), NULL);
FreeLibrary(hDll);
}
}
if (!bOk)
{
wnsprintfW(wszBuf, _countof(wszBuf), L"code %#I32x", dwError);
}
return wszBuf;
}
};
typedef GetWin32ErrorEx<char> GetWin32ErrorA;
typedef GetWin32ErrorEx<wchar_t> GetWin32ErrorW;
typedef GetWin32ErrorEx<TCHAR> GetWin32Error;
PCCH GetWinHttpError(DWORD dwLastError)
{
switch (dwLastError)
{
case ERROR_WINHTTP_OUT_OF_HANDLES:
return"ERROR_WINHTTP_OUT_OF_HANDLES";
case ERROR_WINHTTP_TIMEOUT:
return"ERROR_WINHTTP_TIMEOUT";
case ERROR_WINHTTP_INTERNAL_ERROR:
return"ERROR_WINHTTP_INTERNAL_ERROR";
case ERROR_WINHTTP_INVALID_URL:
return"ERROR_WINHTTP_INVALID_URL";
// ... дальше все ошибки для winhttp.dll to be continued...
}
return"WinHttp Unknown";
}
struct excpt
{
enum{cchSize = 256};
char szMsg[cchSize];
DWORD dwLastError;
excpt()
{
DWORD dwLastError = GetLastError();
DWORD dwCode = dwLastError & 0x0000FFFF;
if (dwCode > WINHTTP_ERROR_BASE && dwCode < WINHTTP_ERROR_LAST)
{
// get winhttp error desription
lstrcpynA(szMsg, GetWinHttpError(dwCode), _countof(szMsg));
}
else
{
// get winapi or ole error description
lstrcpynA(szMsg, GetWin32ErrorA(dwLastError), _countof(szMsg));
}
this->dwLastError = dwLastError;
}
// сделал этот конструктор для своих ошибок но пока мне хватает и
// стандартных из winerror.h
excpt(DWORD dwLastError, PCCH pszMessage)
{
lstrcpynA(szMsg, pszMessage, _countof(szMsg));
this->dwLastError = dwLastError;
}
};