Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет J>делаю некий модуль которому надо как то сообщать об ошибках хочется следующее J>например ошибка модуля (логическая или еще какая но своя) просто кинуть код J>... J>а как это правильно сделать ?
А что, сделать по классу исключений на каждый тип ошибки нельзя?
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет J>делаю некий модуль которому надо как то сообщать об ошибках хочется следующее J>например ошибка модуля (логическая или еще какая но своя) просто кинуть код
J>а как это правильно сделать ?
не понятно что тебе надо логировать ошибку или её обрабатывать? Исключения придуманы как гибкий механизм обработки ошибок, а не логировая. Если ты их просто логируешь, то это надо делать в месте возникновения ошибки. Если ошибка должна быть обработана заведи класс для каждого типа ошибок и отнаследуй от std::exception. То, что ты делаешь похоже на попытку избежать множества if(error) {print(error); return error;}, а не для нормального уведомления пользователя об ошибках.
Всем привет
делаю некий модуль которому надо как то сообщать об ошибках хочется следующее
например ошибка модуля (логическая или еще какая но своя) просто кинуть код
а как это правильно сделать ?
вообще как в такой ситуации правильно обработку ошибок сделать ?
какие ограничения: использовать можно весь C рантайм из msvcrt.dll она линкуется как внешняя библиотека
кроме msvcpXX.dll статически ее слинковать тоже нельзя ибо размер прог с компонентом должен быть небольшой
Здравствуйте, ST1, Вы писали:
ST1>>>Использование универсально для любого msg типа char * V>>Какой бесконечный ужас и кошмар...
ST1>о std::string такого же мнения?
Разумеется. У разных исключений должны быть разные типы.
Здравствуйте, ST1, Вы писали:
ST1>Ребят, не ленитесь пройти по ссылке и изучить стоящий код, а мой пример лишь иллюстрация возможного использования.
Чтобы не писал этот неизвестный человек, но твой подход с макросами это не С++, а С. Фактически ты пишешь в лог место возникновения ошибки и делаешь return. Это очень напоминает С подход с goto когда есть требование одного входа/выхода из функции. Ты даже не пытаешься обработать ошибку, просто логируешь. Советую прочитать "Совершенный Код" Макконнела галву про исключения и про ошибки.
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;
}
};