Форум » Clipper » Обработчик ошибок » Ответить

Обработчик ошибок

DeF: Нужен самопальный обработчик ошибок, которій по максимуму просекает все возможные ошибки в ходе работы программы, пишет детальный лог-файл и старается удержать программу "на плаву". Спасибо!

Ответов - 13

ort: А что, такой в природе есть?

suv2: смотри в SOURCE\SYS\errorsys.prg зы. Не забудь, что лог должен быть локальный, сеть бывает пропадает и получается ошибка в ошибке

DeF: suv2 Юра... Нужен готовый, чтобы прикрутил и пошло-поехало... лопатить стандартный не охота :( ЗЫ. неужели ты думаешь, что первой мыслью не было смотреть именно в SOURCE\SYS\errorsys.prg ??? :)


Sergy: [code] /*** * Errorsys.prg * * Компилировать с опциями /m/n/w */ #include "error.ch" ANNOUNCE _ntxerr // Вывод сообщений на устройство STDERR - заблокирован - вывод в файл // #command ? <list,...> => ?? Chr(13) + Chr(10) ; ?? <list> // #command ?? <list,...> => OutErr(<list>) // Используется ниже #ifndef NTRIM #define NTRIM(n) ( LTrim(Str(n)) ) #endif /*** * ErrorSys() * * Замечание: Автоматически запускается при начале работы */ PROC ErrorSys() ErrorBlock( {|e| DefError(e)} ) RETURN FUNC ErrorExitProgram() DefError(ERRORNEW()) RETURN /****************************** * DefError() *******************************/ STATIC FUNC DefError(e) LOCAL i, cMessage, aOptions, nChoice LOCAL fname:="report.log" IF (e:genCode == EG_ZERODIV) // По умолчанию деление на ноль дает ноль RETURN (0) ENDI IF (e:SubSystem == 'DBFNTX') .AND. ; // специфика dbfntx & Win2K based servers (e:SubCode == 1035) .AND. ; (e:tries < 25) RETURN (.T.) ENDI IF (e:genCode == EG_LOCK) .AND. e:canDefault // обработка специфич.ошибки ntx в 5.2e RETURN (.F.) ENDI IF (e:genCode == EG_OPEN) .AND. (e:osCode == 32) .AND. e:canDefault // Для ошибки открытия файла в сетевом окружении..установка NETERR() // и значения SUBSYSTEM по умолчанию NetErr(.T.) RETURN (.F.) // NOTE ENDI IF (e:genCode == EG_APPENDLOCK) .AND. e:canDefault // Для ошибки блокировки во время APPEND BLANK..установка NETERR() // и значения SUBSYSTEM по умолчанию NetErr(.T.) RETURN (.F.) // NOTE END IF err_dejavu // определи где-нибудь перемнную PUBLIC или STATIC модуля QUIT ENDI err_dejavu:=.T. // Построение сообщения об ошибке cMessage := ErrorMessage(e) // Построение массива позиций для выбора // aOptions := {"Прервать", "Завершить"} // 1,2 aOptions := {"Завершить"} // 1 IF (e:canRetry) AAdd(aOptions, "Повторить") // 2 END IF (e:canDefault) AAdd(aOptions, "Пропустить") // 3 END // активизация ALERT-меню nChoice := 0 WHILE ( nChoice == 0 ) IF ( Empty(e:osCode) ) nChoice := Alert( cMessage, aOptions ) ELSE nChoice := Alert( cMessage + ; ";(Код DOS-ошибки: "+NTRIM(e:osCode)+") = "+DosErrText(e:osCode), ; aOptions ) END IF (nChoice == NIL); EXIT; ENDI END IF !EMPTY(nChoice) // Выполнение по инструкции оператора IF nChoice == 2 // Повторить - Retry err_dejavu:=.F. RETURN (.t.) ELSEIF (nChoice == 3) // Пропустить - Default err_dejavu:=.F. RETURN (.f.) END END // Отображение сообщения и стека вызов процедур (при Завершить) IF !EMPTY(e:osCode) cMessage += CHR(13)+CHR(10)+"Код DOS-ошибки: "+NTRIM(e:osCode)+" ("+DosErrText(e:osCode)+")" END SET DEFAULT TO SET CONSOLE ON SET ALTERNATE TO (fname) ADDITIVE SET ALTERNATE ON //////////////// ниже используются некоторые сист..переменные и мои функции - //////////////// для определения условий, в которых произошла ошибка ? ? DATE(), TIME(), current_user[2],"@",work_dir,"#e =",NTRIM(err_count) IF TYPE("t_edit_params") = "A" ? LINE(30) ? "Версия :",ALLTRIM(STR(t_edit_counter)),"от",t_edit_date ENDI ? cMessage ? i := 2 WHILE (!EMPTY(PROCNAME(i))) ? "Вызов из ", TRIM(PROCNAME(i)) + "(" + NTRIM(PROCLINE(i)) + ")" i++ END SaveVars() // моя функйция сохранения переменных, можно выкинуть ? "Информация сохранена." ? SET ALTERNATE OFF CLOSE ALTERNATE // пытаемся слить состояние памяти STRFILE(CRLF+ShowFreeMem(,,,TRUE)+CRLF,fname,TRUE) // можно выкинуть // Возврат в DOS ERRORLEVEL(1) // ошибка! ExitProgram() err_dejavu:=.F. RETURN (.f.) * -------------------------------- * STATIC FUNC DosErrText(nCode) LOCAL res:=NTRIM(nCode) IF nCode= 2; res:="Файл не найден" ELSEIF nCode= 3; res:="Путь доступа не найден" ELSEIF nCode= 4; res:="Слишком много откр.файлов,;нет свободных дескрипторов" ELSEIF nCode= 5; res:="Отказ в доступе" ELSEIF nCode= 6; res:="Недействительный дескриптор файла" ELSEIF nCode= 7; res:="Нарушен блок упр.распред.памяти" ELSEIF nCode= 8; res:="Недостаточно памяти" ELSEIF nCode=32; res:="Ошибка совместного доступа к файлу" ELSEIF nCode=51; res:="Удаленный компьютер не отвечает" ELSEIF nCode=53; res:="Сетевое имя не найдено" ELSEIF nCode=80; res:="Файл уже существует" ENDI RETURN res * ----------------------- * STATIC FUNC ErrorMessage(e) LOCAL cMessage // Начало сообщения об ошибке cMessage := IIF( e:severity > ES_WARNING, "Ошибка ", "Предупреждение " ) // добавление имени подсистемы (если доступно) IF ( VALTYPE(e:subsystem) == "C" ); cMessage += e:subsystem() ELSE; cMessage += "???" ENDI // добавление SUBSYSTEM кода ошибки (если доступно) IF ( VALTYPE(e:subCode) == "N" ); cMessage += ("/" + NTRIM(e:subCode)) ELSE; cMessage += "/???" ENDI // добавление описания ошибки (если доступно) IF ( VALTYPE(e:description) == "C" ) cMessage += (" " + e:description) ENDI // добавление либо FILENAME, либо названия операции IF (!EMPTY(e:filename)); cMessage += (": " + e:filename) ELSEIF (!Empty(e:operation)); cMessage += (": " + e:operation) ENDI RETURN (cMessage) [/code]

DeF: Sergy спасибо за реальную помощь... попробую прикрутить

suv2: DeF пишет: suv2 Юра... Нужен готовый, чтобы прикрутил и пошло-поехало... лопатить стандартный не охота :( ЗЫ. неужели ты думаешь, что первой мыслью не было смотреть именно в SOURCE\SYS\errorsys.prg ??? :) шо щзначит "готовый"? Чем тебе тот не готовый? зы. Ошибки маскировать - послденее дело. Ошибки - сигнал о том, шо шо-то неправильно я вот даже деление на ноль не маскирую... не говоря уже о том, чтобы маскировать всякую сетевуху!!! вываливается - пизды админу, значит у него сеть хуевая, рипитеры сслабые и глючные, концы обжаты хреново, сеть перегружена, пусть программирует маршруты и тп.

suv2: админ будет хуи пинать, а ты его плохую работу будешь в еррорсис маскировать? пшел он на хуй

Sergy: Юра, подскажи пожалуйста, в каком месте нужно у винды "подкрутить", чтобы не приходилось маскировать эти ошибки ? Дело в том, что DBFNTX/1035 возникает при ЛОКАЛЬНОМ размещении таблицы, а об EG_LOCK написано на ОФИЦИАЛЬНОМ NG! Можно, конечно, свалить всё на админа , опустить ему почки, наставить фингалов под глазами , но если разобраться по сути...

suv2: ХЗ.... Все время читаю страшные вещи про жуткие траблы с досом в XP... То сетевые устройства она кэширует в досе, то что-то там долго держит и не отпускает. И даже предлагаются какие-то там параметры в реестре менять... хрен вас знает, где вы такие винды берете... Ставим нормальную WinXP SP2 на нормальное железо - все работает сразу и без нареканий. Никаких ошибок блокироваки тем более на локальнмо устройстве быть не может и не должно. Если есть - сносите все нах и переставляейте винды

Sergy: Win XP SP2 - сервером ???????????? Речь шла про Win2003 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! с WinXP как раз - никаких проблем. (тьфу*3)

ZAlex: Ну и где речь шла про сервер Win2003? Вопрос был общего плана.

suv2: Sergy пишет: Win XP SP2 - сервером ???????????? Речь шла про Win2003 фрагменты "сервер" и "2003" в этой теме ДО твоего сообщения не встречаются

Sergy: просто так получилось, что одновременно с этой веткой я обсуждал этот вопрос здесь и заглушка для ошибки DBFNTX/1035 появилась в этом обработчике именно по такой причине.



полная версия страницы