← →
Ануфрий
(2007-08-03 19:30)
[0]
С некоторых пор Дельфи стал показывать сообщения об ошибках (исключениях), которые пойманы через try.
Т.е. код до этого
try
I := деление на ноль;
finally
end
Приводил к тому, что в режиме отладки дельфи сообщал об ошибке, и после нажатия F9 программа дальше работала. Без дельфи прога вообще ничего не выдавала.
Теперь показывается сообщение дельфи и после F9 вылетает MessageBox.
А если запускать без дельфи, то просто вылетает MessageBox (типа деление на ноль).
Раньше все было нормально, не пойму что случилось и как это убрать.
![]()
![]()
← →
Dib@zol ©
(2007-08-03 19:32)
[1]
А может просто не делить на ноль??? Или это просто такой пример?
![]()
![]()
← →
Ануфрий
(2007-08-03 19:35)
[2]
Это пример.
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 19:39)
[3]
> Ануфрий (03.08.2007 19:35:02) [2]
В этом примере не делить на ноль.
![]()
![]()
← →
Ануфрий
(2007-08-03 19:42)
[4]
Ну тогда другой пример.
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get("http://my_domain.com");
finally
HTTP.Free;
end;
end;
При запуске вызывается исключение (сайт не найден). Мне нужно чтобы на экран не выдавалось сообщение с текстом исключения.
![]()
![]()
← →
Dib@zol ©
(2007-08-03 19:43)
[5]
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get(«http://my_domain.com»);
finally
HTTP.Free;
end;
end;
try..finally заменяй на try..except.
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 19:45)
[6]
> Ануфрий (03.08.2007 19:42:04) [4]
Чтобы на экран не выдавалось сообщение, исключение надо обработать самому, это блок try except end
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 19:46)
[7]
> Dib@zol (03.08.2007 19:43:05) [5]
try..finally убирать нельзя, это будет уже другая ошибка дизайна, например утечка как минимум
![]()
![]()
← →
Ануфрий
(2007-08-03 19:49)
[8]
Dib@zol
Спасибо, работает. Хотя я всегда думал, что finally также «поглощает» ошибки, как except, только в отличие от последнего вызывается всегда, даже если ошибок нет. И вроде бы так и работало… Может просто не разу ошибок не попадалось внутри try finally end;
![]()
![]()
← →
Ануфрий
(2007-08-03 19:52)
[9]
Anatoly Podgoretsky
Так нужно делать вложенные try что-ли?var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
try
Str := HTTP.Get("http://my_domain.com");
except
end;
finally
HTTP.Free;
end;
end;
Тогда наверное проще заменить наvar
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get("http://my_domain.com");
except
end;
HTTP.Free;
end;
?
![]()
![]()
← →
Ануфрий
(2007-08-03 19:56)
[10]
Посмотрел старый код. Раньше у меня тоже было try finally end. И никогда ошибки на экран не выдавались.
![]()
![]()
← →
Zagaevskiy ©
(2007-08-03 19:57)
[11]
Может ошибок там не было?
![]()
![]()
← →
Инс ©
(2007-08-03 19:57)
[12]
> Тогда наверное проще заменить на
В данном конкретном случае можно, но вообще лучше 1-й вариант.
![]()
![]()
← →
{RASkov} ©
(2007-08-03 19:58)
[13]
> [9] Ануфрий (03.08.07 19:52)
> Тогда наверное проще заменить на
> var
> HTTP: TIdHTTP;
> Str: string;
> begin
> HTTP := TIdHTTP.Create(nil);
> try
> Str := HTTP.Get(«http://my_domain.com»);
> except
> end;
> HTTP.Free;
> end;
> ?
Не верно!
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
try
Str := HTTP.Get("http://my_domain.com");
except
ShowMessage("Произошла ошибка такая-то");
end;
finally
HTTP.Free;
end;
end;
![]()
![]()
← →
Инс ©
(2007-08-03 19:58)
[14]
> [10] Ануфрий (03.08.07 19:56)
Почитай Рихтера, у него отлично механизм исключений расписан.
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 20:01)
[15]
> Ануфрий (03.08.2007 19:52:09) [9]
Для данного кода можно написать с одним блоком, но обычно код сложнее и
except
end
Лучше заменить на
except
что то полезное.
end
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 20:08)
[16]
> Anatoly Podgoretsky (03.08.2007 20:01:15) [15]
Хотя бы на
except
on E.Exception do begin
// variable := E.Message
//или
// LOG(llCriticalLevel, «Ошибка HTTP.Get(http://my_domain.com) = » + E.Message);
end;
end
Это позволит как минимум поставить точку останова для отладки.
![]()
![]()
← →
Ануфрий
(2007-08-03 20:10)
[17]
Все, спасибо всем, просто заработался.
function GetBody(const URL: string): string;
var
HTTP: TIdHTTP;
Str: string;
begin
Result := "";
HTTP := TIdHTTP.Create(nil);
try
Result := HTTP.Get("http://my_domain.com");
finally
HTTP.Free;
end;
end;
а далее вызов так
try
S := GetBody("http://domain.com");
except
S := "";
end;
потому ошибки не было. А когда я начал разбираться с GetBody, видел только finally и это меня смутило, почему вдруг стали ошибки появляться. 🙂
![]()
![]()
← →
Anatoly Podgoretsky ©
(2007-08-03 20:23)
[18]
> Ануфрий (03.08.2007 20:10:17) [17]
Вот это грамотный код.
![]()
![]()
At the moment I have a Delphi form running and upon losing connection to its Database/loss of network, it re-establishes and carries on.
The service is on a timer and each minute, it pops up with message box saying failure to connected to db on network [ip address]. This is at the start of the timer, a stored proc is ran.
I have all errors writing to a log file on the service local machine, is there a way I can suppress the message box appearing as I don’t need it to appear all the time? by message box it is a windows exception box not a showMessageBox(). It automatically pops up when the exception hits but it will continuously hit whilst the machine boots up and re-establishes connection to the network.
The code I have is as follows
(*Call db Procedure*)
try
db.SQL.Clear;
db.SQL.Add('call dbProc();');
db.ExecSQL;
except
On E : Exception Do
begin
If E.ClassName = 'EIBInterBaseError' Then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectdb;
end
else if E.ClassName = 'EADOError' then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectDB;
end;
end;
end;
At the moment I have a Delphi form running and upon losing connection to its Database/loss of network, it re-establishes and carries on.
The service is on a timer and each minute, it pops up with message box saying failure to connected to db on network [ip address]. This is at the start of the timer, a stored proc is ran.
I have all errors writing to a log file on the service local machine, is there a way I can suppress the message box appearing as I don’t need it to appear all the time? by message box it is a windows exception box not a showMessageBox(). It automatically pops up when the exception hits but it will continuously hit whilst the machine boots up and re-establishes connection to the network.
The code I have is as follows
(*Call db Procedure*)
try
db.SQL.Clear;
db.SQL.Add('call dbProc();');
db.ExecSQL;
except
On E : Exception Do
begin
If E.ClassName = 'EIBInterBaseError' Then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectdb;
end
else if E.ClassName = 'EADOError' then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectDB;
end;
end;
end;

настройка компилятора — не показывать ошибки
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
|
|
Full Member
Рейтинг (т): 1 |
юзаю try except… запускаю прогу в компиляторе — всеравно выдает ошибку Собственно как отключить эту штуку в компиляторе что бы спокойно можно было из компилятора запускать?? Сообщение отредактировано: 8ka — 06.01.11, 19:57 |
|
CodeMonkey |
|
|
Tools/Options/Debugger/Stop on exceptions. |
|
northener |
|
|
Цитата 8ka @ 06.01.11, 19:56 Собственно как отключить эту штуку в компиляторе что бы спокойно можно было из компилятора запускать??
Не надо это делать! |
|
Alexander N |
|
|
Цитата northener @ 07.01.11, 00:58 Хотя я не понимаю для чего это нужно! Было нужно. Поиск файлов-дубликатов на диске — здесь я обрабатываю неудачное открытие файла одним оператором continue, но таких файлов много, поэтому было напряжно каждый раз закрывать окошко ошибки. |
|
leo |
|
|
Цитата Alexander N @ 07.01.11, 06:37 Было нужно. Поиск файлов-дубликатов на диске — здесь я обрабатываю неудачное открытие файла одним оператором continue, но таких файлов много Если «таких файлов много», то это уже не исключительная ситуация, а вполне штатная, поэтому логичнее было бы просто (локально) отключить генерацию исключений при открытии файлов по {$I-} и проверять успешность по IOResult |
|
Alexander N |
|
|
Цитата leo @ 07.01.11, 09:40 Если «таких файлов много», то это уже не исключительная ситуация, а вполне штатная, поэтому логичнее было бы просто (локально) отключить генерацию исключений при открытии файлов по {$I-} и проверять успешность по IOResult Как? Я же через TFileStream работал? Сообщение отредактировано: Alexander N — 07.01.11, 10:28 |
|
leo |
|
|
Цитата Alexander N @ 07.01.11, 10:24 Как? Я же через TFileStream работал?
Еще лучше — значит нужно было работать через THandleStream + FileOpenFileClose без всяких IOResult |
|
Alexander N |
|
|
Цитата leo @ 07.01.11, 10:50 Еще лучше — значит нужно было работать через THandleStream + FileOpenFileClose без всяких IOResult А как позицию хранить? Блоками читать? |
|
leo |
|
|
Цитата Alexander N @ 07.01.11, 10:53 А как позицию хранить? Блоками читать?
О чем это ты ? TFileStream это совершенно куций фантик для THandleStream, и делает он всего две элементарные вещи: Добавлено 07.01.11, 11:43
var h:integer; strm:THandleStream; begin … h:=FileOpen(FName,Mode); if h >= 0 then begin strm:=THandleStream.Create(h); try … finally strm.Free; FileClose(h); end; end else … //ошибка открытия файла GetLastError end; Сообщение отредактировано: leo — 07.01.11, 11:44 |
|
Alexander N |
|
|
А у меня массив из TFileStream — как его заменить? Добавлено 07.01.11, 11:57 |
|
leo |
|
|
Цитата Alexander N @ 07.01.11, 11:57 А у меня массив из TFileStream — как его заменить?
Час от часу не легче
type TMyFileStream = class(THandleStream) destructor Destroy;override; end; destructor TMyFileStream.Destroy; begin if Handle >= 0 then FileClose(Handle); inherited; end; var files:array of TMyFileStream; h:integer; begin … h:=FileOpen(FName,Mode); if h >= 0 then begin SetLength(files,Length(files)+1); files[Length(files)-1]:=TMyFileStream.Create(h); … end else … //GetLastError end; |
|
Alexander N |
|
|
Цитата leo @ 07.01.11, 12:44 Ну определи тогда свой класс, который будет закрывать файл в деструкторе Ну а зачем, если уже есть TFileStream и его хватает с лихвой? |
|
leo |
|
|
Цитата Alexander N @ 07.01.11, 13:04 Ну а зачем, если уже есть TFileStream и его хватает с лихвой?
Ага с очень большой лихвой, упомянутой тобой в #4 Сообщение отредактировано: leo — 07.01.11, 15:39 |
|
Alexander N |
|
|
Цитата leo @ 07.01.11, 15:38 но и всю систему в целом Каким образом? |
|
Демо |
|
|
Установка флага Tools/Options/Debugger/Stop on Delphi exceptions в «on» нужна в очень редких случаях (таких даже не припомню). Используется только для отладки. Обработка исключений — необходимая и нормальная вещь внутри программы. Ко всему прочему, есть компоненты, которые сами обрабатывают исключения (и и гасят их как нужно). Сообщение отредактировано: Демо — 07.01.11, 17:05 |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0531 ] [ 16 queries used ] [ Generated: 28.01.23, 18:02 GMT ]
Большинство сообщений об исключениях можно подавить, обработав TApplication.OnException событие. Объект приложения отображает сообщение об исключении, только если этому событию не назначен обработчик. Вы можете позвонить TApplication.ShowException в вашем обработчике для определенных исключений, если хотите.
Это событие запускается для исключений, возникающих во время работы в цикле сообщений VCL. Исключения, возникающие в другом месте, завершают вашу программу или текущий поток. Кроме того, событие запускается только для исключений, происходящих от Exception; исключения, которые происходят от других классов, передаются непосредственно в SysUtils.ShowException.
Независимо от того, показываете вы сообщение или нет, ваша программа все еще находится в неопределенном состоянии после возникновения исключения, которое вы не обработали. Простое подавление сообщения сродни сметанию пыли под ковер. Лучше всего использовать такой инструмент для регистрации исключений, как MadExcept, ЭврикаЛог или JclDebug который записывает информацию об исключении и дает вашим клиентам возможность отправить вам отчеты, чтобы вы могли воспроизвести условия ошибки и исправить ее.



