
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Сообщ.
#1
,
|
|
|
Подскажите, можно ли как нибудь отловить код ошибки?
Объясняю на примере: Вот отлавливает деление на ноль, к примеру: ![]() ![]() //readln(A); =0; try Z:=Z/A; except on E: exception do ShowMessage(e.messages); end; Ну это конечно ясно, что он напишет 'Division by zero', но это во-первых по английски, а во вторых, если мы напишем сразу сообщение по русски, т.е. так: ![]() ![]() //readln(A); =0; try Z:=Z/A; except ShowMessage('Деление на ноль!'); end; и допустим, что ошибка произошла не из-за того, что делится на ноль, а из-за чего-нибудь другова - то естественно сообщение будет ложным, а точнее неверным. И что делать? Типа есть такой вариант, но тупой: ![]() ![]() //readln(A); =0; try Z:=Z/A; except on E: exception do if (e.messages='Division by zero') then ShowMessage('Деление на ноль') else ShowMessage(e.messages); end; Почему вариант тупой, да потому что, перед тем как вставить текст сообщения об ошибке надо: 1. Сделать эту ошибку 2. вывести её на экран 3. скопировать её текст "символ в символ" 4. потом вставить это сообщение в код для сравнения. Хочется что-то типа того, что текст ошибки сообщения мог бы заменять какой-нибудь её индетификатор, чтобы можно было типа такого: ![]() ![]() //readln(A); =0; try Z:=Z/A; except on E: exception do if (e.код_ошибки=123) then ShowMessage('Деление на ноль') else ShowMessage(e.messages); end; где "123" есть индетификатор ошибки, т.е. заменяет сам текст 'Division by zero'. Да, и у e нет параметра на английском, что я написал на русском код_ошибки. Ууууу.... Пока писал - сам устал. ![]() Если кто поймёт меня, помогите разобраться. |
Сообщ.
#2
,
|
|
|
Сообщ.
#3
,
|
|
|
Спасибо за ссылку.
А вот в каком модуле находятся классы исключений при работе с ibx компонентами. Т.е. мне надо вот к примеру такой класс исключения: ![]() ![]() except on E: EIBInterBaseError do begin sShowMessage(e.ClassName,e.Message); exit; end; а он мне пишет: Неизвестная переменная EIBInterBaseError Вообще класс такой есть, он даже его показывает, если я делаю так: ![]() ![]() try Connected:=true; except on E: exception do sShowMessage(e.ClassName,e.Message); end; Вот e.ClassName как раз и есть EIBInterBaseError, только я не могу класс коде указать. |
Сообщ.
#4
,
|
|
|
Хелп говорит, что EIBInterBaseError находится в юните IB
|
Сообщ.
#5
,
|
|
|
Цитата Continental @ А вот в каком модуле находятся классы исключений при работе с ibx компонентами. Пуск/Поиск. *.pas с текстом EIBInterBaseError. Для ускорения поиска лучше ткнуть в папку Delphi. Цитата Continental @ Вообще класс такой есть, он даже его показывает, если я делаю так Вместо ![]() ![]() except on E: SomeClass do ... можно (но не рекомендуется) использовать: ![]() ![]() except on E: Exception do if E.ClassName = 'SomeClass' then ... else raise; |
Сообщ.
#6
,
|
|
|
ММММ.... всё равно прочитав всё, не могу реализовать то что я хочу.
Вот к примеру: 1. я указываю несуществующий путь к БД в TIBDataBase. Делаю подключение и try показывает ошибку класса EIBDataBaseError, при этом вот такой текст ошибки: 'I\O Error ....и т.д.'. 2. я указываю существующий путь к БД в TIBDataBase. Указываю неверный логин или верный логин, но неверный пароль и мне ошибка класса EIBDataBaseError, но текст сообщения уже другой! Текст такой: 'Your user name .... are not defined. ...'. Так вот я хочу сказать, что в двух случаях ошибки совсем разные, а вот класс исключения один и тот же. Так я не могу понять, как же мне отловить первую ошибку, или вторую вот с помощью такой конструкции: ![]() ![]() try IBDataBase.Connected:=true; except on E : что здесь должно быть, чтобы определить 1-й случай? do begin sShowMessage('несуществующий путь бд!'); exit; end; on E : что здесь должно быть, чтобы определить 2-й случай? do begin sShowMessage('неверный пользователь или пароль'); exit; end; on E : Exception do begin //люая другая ошибка sShowMessage(e.ClassName,E.Message+' совершенно другая ошибка'); exit; end; end; Помогите разобраться пожалуйста, я очень хочу сделать так, но не знаю. |
Сообщ.
#7
,
|
|
|
Цитата Continental @ Так вот я хочу сказать, что в двух случаях ошибки совсем разные, а вот класс исключения один и тот же. Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode - то это криво спроектированные классы Interbase. Цитата Continental @ Так я не могу понять, как же мне отловить первую ошибку, или вторую вот с помощью такой конструкции: Если никакого поля с кодом нет, то по-хорошему - никак. (Т.е. вы можете, конечно, попробовать анализировать сообщение, но ведь его могут локализовать). Добавлено P.P.S. Если же поле кода есть, то в общем случае как-то так: ![]() ![]() try IBDataBase.Connected:=true; except on E: EIBDataBaseError do if E.ErrorCode = XXX then begin sShowMessage('несуществующий путь бд!'); exit; end else if E.ErrorCode = YYY then begin sShowMessage('неверный пользователь или пароль'); exit; end else raise; end; Добавлено Или: ![]() ![]() try IBDataBase.Connected:=true; except on E: Exception do begin if E is EIBDataBaseError then begin if EIBDataBaseError(E).ErrorCode = XXX then begin sShowMessage('несуществующий путь бд!'); exit; end else if EIBDataBaseError(E).ErrorCode = YYY then begin sShowMessage('неверный пользователь или пароль'); exit; end; end; ShowMessage(e.ClassName,E.Message+' совершенно другая ошибка'); end; end; Добавлено P.P.P.S. Но в общем и целом, если вам это нужно только для показа сообщения об ошибке "на русском", то лучше бы вам локализовать константы вместо того, чтобы ставить кучу обработчиков по всей программе. |
Сообщ.
#8
,
|
|
|
Цитата CodeMonkey @ Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode Именно так это свойство и называется, что нетрудно узнать из хелпа (который надеется на длительное и плодотворное сотрудничество с Continental ![]() Значения этих кодов прописаны в файле IBErrorCodes.pas (ищи его где-нибудь в C:\Program Files\Borland\Delphi7\Source\Vcl\IBErrorCodes.pas, к примеру) |
Сообщ.
#9
,
|
|
|
С облегчением ...
![]() ![]() ![]() try Connected:=true; except on E : EIBInterBaseError do begin sShowMessage(IntToStr(e.IBErrorCode),E.Message); exit; end; Спасибо всем, что открыли глаза. Добавлено О! вообще круто! CodeMonkey, спасибо что подсказали вот это ![]() ![]() except on E: Exception do begin if E is EIBDataBaseError then begin if EIBDataBaseError(E).ErrorCode = XXX then Я теперь это заделал в applicationevents. Теперь у меня будет и лог вестись и сообщения об ошибках выводится! Е-Е-Е! |
Сообщ.
#10
,
|
|
|
Для лога ошибок имеет смысл использовать хук на исключения. См. JCL, EurekaLog, madExcept. Помимо сообщения этот способ позволит получить стек вызовов и состояние процессора в момент ошибки. С этой информацией зачастую продиагностировать ошибку можно даже не запуская отладчик.
|