Форум: "Прочее";
Текущий архив: 2012.01.01;
Скачать: [xml.tar.bz2];
ВнизОда молодому поколению Найти похожие ветки
← →
Romkin © (2011-09-08 16:15) [160]Почему? Простейший глобальный обработчик.
Выдачу диалогового окна из консольного приложения я считаю вообще недопустимым: ошибка должна рапортоваться в stderr (хотя и в stdout тоже допустимо), плюс ExitCode устанавливаться. И для этого есть несколько простых причин.
И тем более меня удивляет твое неприятие этого.
← →
Игорь Шевченко © (2011-09-08 16:58) [161]
> И тем более меня удивляет твое неприятие этого.
А чему удивляться ?
Я последовательный противник кода вида
on E: Exception do
ShowMessage("Ошибка: "+E.Message);
"Глобальный обработчик", который предлагает Delphi (не знаю, с какой версии, но между 2006 и 2010) ничем, по сути, не отличается от приведенного фрагмента - то есть, не дает никакой информации, почему и где произошла ошибка (call stack), не передает ее (в случае консольных приложений) вызывающему, потому что завершение выполняется по Halt0.
← →
Eraser © (2011-09-08 17:35) [162]> [161] Игорь Шевченко © (08.09.11 16:58)
да можно и глушить, при этом выходя из текущей процедуры. все зависит от специфики проекта. но обязательно должна быть централизованная обработка исключений, с тем самым call stack, который стандартный перехватчик не отображает кстати. для этих целей сгодится JEDI ну или же тяжелая артилерия вроде Evrika.
← →
Игорь Шевченко © (2011-09-08 18:11) [163]Не удержусь в очередной раз, чтобы не привести ссылку
http://delphikingdom.com/asp/viewitem.asp?catalogid=1392
← →
Romkin © (2011-09-08 18:17) [164]
> А чему удивляться ?Я последовательный противник кода видаon
> E: Exception do ShowMessage("Ошибка: "+E.Message);
Я тоже. Но здесь есть разница: консоль при этом завершит работу. Это - демонстрационное приложение, не более. При этом сообщение об ошибке есть, и для данного случая его вполне достаточно.
А твое возмущение реально удивляет.
← →
Romkin © (2011-09-08 18:23) [165]Тем более я не понимаю, почему в исходнике в десяток строчек (в демке!) я должен давать раскрутку стека, подробную информацию об исключении и т.д. Угу, и Эврику еще вставить. Да я быстрее просмотрю весь код и найду ошибку, чем буду читать вывод ошибки :D
А так - покрутил, если что - почитал что выдало в исключении, глянул код.
← →
Игорь Шевченко © (2011-09-08 18:38) [166]
> Тем более я не понимаю, почему в исходнике в десяток строчек
> (в демке!) я должен давать раскрутку стека, подробную информацию
> об исключении и т.д.
Я точно также не понимаю, зачем в демке нужна такая обработка исключений - покрутить и посмотреть ты можешь и без нее. Разве что лень вытирать сгеренированный средой уродский код.
← →
DVM © (2011-09-08 18:49) [167]
> Игорь Шевченко ©
Ты предлагаешь в консольных приложениях и сервисах исключения не давить совсем? Я правильно понимаю? Или не понимаю.
← →
Игорь Шевченко © (2011-09-08 18:58) [168]DVM © (08.09.11 18:49) [167]
Ты не понимаешь :)
Я ссылку в [163] дал - там довольно складно написано, как, когда и зачем обрабатывать исключения.
В двух словах - сообщение об ошибке должно помочь ее локализовать и по возможности исправить.
← →
DVM © (2011-09-08 19:05) [169]
> Игорь Шевченко © (08.09.11 18:58) [168]
> Я ссылку в [163] дал
я читал раньше, там все верно написано
> В двух словах - сообщение об ошибке должно помочь ее локализовать
> и по возможности исправить.
Это да, для этого я почти всегда использую именованные потоки, чтобы логгировать имя потока вместе с информацией исключения и стараюсь (если генерирую исключения сам) добавлять в текст исключения имя класса (если есть) и прочее. А исключения в консольных приложениях и сервисах я давлю. Логгирую и давлю. Логгирование (особенно в сервисах) - тотальное, с настройкой уровня логгирования, что позволяет записать последовательность действий, приводящих к ошибке, хотя бы по мере возможности. Эврику не использую.
← →
Rouse_ © (2011-09-08 19:26) [170]Хм, а я в сервисах логирование с раскруткой стека вызовов и SEH-фреймов делаю, а потом давлю, ибо нефих - и ошибка нормально локализируется и сервис работает дальше :)
← →
DVM © (2011-09-08 19:29) [171]
> Rouse_ © (08.09.11 19:26) [170]
> а я в сервисах логирование с раскруткой стека вызовов и
> SEH-фреймов делаю
Чем делаешь? Свое что-то?
← →
Rouse_ © (2011-09-08 19:32) [172]Ну не с нуля конечно писанное, принцип подсмотрен в JEDI, а так-то да, ручками...
← →
DVM © (2011-09-08 19:34) [173]
> Rouse_ © (08.09.11 19:32) [172]
я вот тоже думал, но как то монструозно выходит для записи малозначительных исключений, типа "не могу подключиться к серверу" или там "файл не найден", "доступ запрещен". Вываливать в лог кучу данных как то оно не очень каждый раз.
← →
Игорь Шевченко © (2011-09-08 19:38) [174]DVM © (08.09.11 19:34) [173]
Для исключения типа "файл не найден" стек и не очень нужен. Стек хорош для поиска ошибок программиста, а не ошибок пользователя.
← →
Rouse_ © (2011-09-08 19:39) [175]Не, такие банальности давятся сразу, ну за исключением "не могу подключиться к серверу".
Просто добавляется описание объекта по которому произошла ошибка + стэк вызовов (ибо мест возникновения данной ошибки может быть много).
А с подключением выдается полная раскладка, с параметрами подключения и т.д. + опять-же стек вызовов.
Для неизвестных ошибок раскрутка стэка и фреймов...
← →
Rouse_ © (2011-09-08 19:40) [176]Зы: по поводу монструозно, я вывод ошибок в несколько файлов делаю, известные (по группам) и неизвестные - ака критические на которые стоит обратить внимание в первую очередь.
← →
DVM © (2011-09-08 19:40) [177]
> Игорь Шевченко © (08.09.11 19:38) [174]
> Для исключения типа "файл не найден" стек и не очень нужен.
>
вот и я о том же, но так как обработка исключений чаще всего централизованная в пределах одного потока по крайней мере, то выводить стек я и не стал.
← →
SQLEX © (2011-09-08 22:00) [178]из той же статьи.
Имейте в виду, что здесь речь идёт именно о перехвате и заглатывании исключений. Ничего плохого в таком коде нет:
function GetSomeObject: TMyObject;
begin
Result := TMyObject.Create;
try
// заполнение Result
except
on Exception do
begin
FreeAndNil(Result); // заботимся, чтобы не было утечек ресурсов
raise; // мы НЕ перехватываем исключения, а только используем их для нотификации.
// Что-то вроде try-finally, но с другой логикой обработки.
end;
end;
end;
а меня ты, Игорь, ругал за
except
on Exception do
begin
:)
← →
Омлет © (2011-09-08 22:33) [179]SQLEX ©
Ну так raise всё меняет.
← →
Игорь Шевченко © (2011-09-08 22:48) [180]SQLEX © (08.09.11 22:00) [178]
Тебя в коммунизм не возьмем - ники меняешь часто :)
← →
Аноним (2011-09-08 23:00) [181]Ба-Бах!!!
← →
Dennis I. Komarov © (2011-09-08 23:04) [182]Эх, бедные студенты... :)
← →
Владислав © (2011-09-09 01:03) [183]Ну так Игорь то, в частности, ведет речь об "on Exception do".
← →
Германн © (2011-09-09 01:21) [184]
> Владислав © (09.09.11 01:03) [183]
>
> Ну так Игорь то, в частности, ведет речь об
Хм.
Об чём ведёт речь Игорь - это ещё тот вопрос. :)
← →
pasha_golub © (2011-09-09 09:16) [185]
> Германн © (09.09.11 01:21) [184]
> Об чём ведёт речь Игорь - это ещё тот вопрос. :)
Соглашусь. :)
← →
Romkin © (2011-09-09 10:22) [186]
> Я точно также не понимаю, зачем в демке нужна такая обработка
> исключений - покрутить и посмотреть ты можешь и без нее.
> Разве что лень вытирать сгеренированный средой уродский
> код.
Код не уродский, об исключении сообщается и программа завершает работу. Такой обработчик вполне подходит для простейших случаев, а большего от него и не требуется, это один из вариантов корректной обработки исключений.
И не надо меня тыкать статьями, я их читал. Часто подобного обработчика совершенно достаточно, чтобы с удобствами локализовать ошибку, особенно в маленьком консольном приложении.
А обработка оставлена - мало ли, может кто-то без среды крутить будет?
← →
_oxffff (2011-09-09 10:45) [187]
> Rouse_ © (08.09.11 19:26) [170]
> Хм, а я в сервисах логирование с раскруткой стека вызовов
> и SEH-фреймов делаю, а потом давлю, ибо нефих - и ошибка
> нормально локализируется и сервис работает дальше :)
Приветствую.
Я предлагал и предлагаю вообще пустой try except в определенных ситуациях использовать. :)
← →
DVM © (2011-09-09 10:46) [188]
> _oxffff
> в определенных ситуациях
в каких?
← →
_oxffff (2011-09-09 10:50) [189]Да и по
on E: Exception do
идут не все исключения.
Поскольку объект обертка не обязан быть подклассом Exception.
Более корректным будет
on E: TObject do
← →
_oxffff (2011-09-09 10:51) [190]
> DVM © (09.09.11 10:46) [188]
Тут была ветка несколько лет назад.
← →
asail © (2011-09-09 11:05) [191]
> Игорь Шевченко © (08.09.11 16:58) [161]
Вот пример из VCL Delphi 6 (unit SvcMgr):procedure TServiceThread.Execute;
var
msg: TMsg;
Started: Boolean;
begin
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE); { Create message queue }
try
FService.Status := csStartPending;
Started := True;
if Assigned(FService.OnStart) then FService.OnStart(FService, Started);
if not Started then Exit;
try
FService.Status := csRunning;
if Assigned(FService.OnExecute) then
FService.OnExecute(FService)
else
ProcessRequests(True);
ProcessRequests(False);
except
on E: Exception do
FService.LogMessage(Format(SServiceFailed,[SExecute, E.Message]));
end;
except
on E: Exception do
FService.LogMessage(Format(SServiceFailed,[SStart, E.Message]));
end;
end;
Как видим, все ексепшены глушатся на корню...
Вот еще оттуда:procedure TService.DoStart;
begin
try
Status := csStartPending;
try
FServiceThread := TServiceThread.Create(Self);
FServiceThread.Resume;
FServiceThread.WaitFor;
FreeAndNil(FServiceThread);
finally
Status := csStopped;
end;
except
on E: Exception do
LogMessage(Format(SServiceFailed,[SExecute, E.Message]));
end;
end;
Видимо, разрабы Борланда (тогда еще) полезных статей не читали... :)
← →
DVM © (2011-09-09 11:07) [192]
> asail © (09.09.11 11:05) [191]
> Как видим, все ексепшены глушатся на корню...
> FService.LogMessage
Где ж они глушатся, они логгируются, так все делают. Я так делаю.
← →
asail © (2011-09-09 12:41) [193]
> DVM © (09.09.11 11:07) [192]
> Где ж они глушатся, они логгируются,
Логгируются, а потом глушатся. Raise там нету...
> так все делают
А вот, Игорь говорит, что так не кошерно... Кто прав? Кого слушать?
> Я так делаю
Я тоже.
← →
Anatoly Podgoretsky © (2011-09-09 12:47) [194]> asail (09.09.2011 12:41:13) [193]
Конечно не кошерно, поскольку скрыто, результат такой же как и при except
end
А о том, что была ошибка и что то записали в лог не узнать.
Так что Raise нужен. Кроме сообщений об ошибке не будет работать логика
отлова ошибки
try
except
....
end
← →
asail © (2011-09-09 12:51) [195]
> Anatoly Podgoretsky © (09.09.11 12:47) [194]
Т.е. VCL в топку, ибо некошерен? Я пральна понял?
← →
DVM © (2011-09-09 12:51) [196]
> Anatoly Podgoretsky © (09.09.11 12:47) [194]
> Так что Raise нужен.
Ага, и сервис будет падать от банальных EFileNotFound и прочих, некритичных ошибок, в то время как мог восстановить работу. Если учесть, что каждую функцию WinApi как правило надо оборачивать в Win32Check, то создать сервис живущий дольше 1 часа в боевых условиях не выйдет. Дело не в том давить или нет, а где давить.
← →
DVM © (2011-09-09 12:56) [197]Хорошо, вот всем пример. Есть сервис, в задачу которого входит, например, какая то последовательная обработка файлов на диске. Для этого в сервисе стартует отдельный поток, в методе Execute которого собственно и производится вся обработка. Поток запускается при старте сервиса и останавливается при остановке. Все остальное время он работает, возможно засыпая когда это необходимо, возможно нет, неважно. Если в Execute не давить исключения, то поток просто умрет. Например, из-за отказа в доступе к очередному файлу. И все. Где логика. Зачем ему умирать.
← →
DVM © (2011-09-09 12:58) [198]
> Anatoly Podgoretsky © (09.09.11 12:47) [194]
> А о том, что была ошибка и что то записали в лог не узнать.
Не поглядев в лог конечно не узнать, как и не узнать о проблемах с любым сервисом. Сервисам администратор нужен, в обязанности которого и входит глядеть в лог.
← →
Компромисс (2011-09-09 13:26) [199]
> Для этого в сервисе стартует отдельный поток, в методе Execute
> которого собственно и производится вся обработка.
Естественно диспетчер должен записать в лог и погасить исключение, потому как он диспетчеризует события, которые друг от друга могут и не зависеть.
А вот если он вдруг обнаружит ошибку в самом себе (то есть дальнейшая работа под угрозой), то он не должен ее гасить, а обязан передать наружу (записав в лог тоже, разумеется).
Это как Windows работает - при ошибке приложения его можно завершить и продолжить работу Windows, но если ошибка в самой Windows, то она и загружаться откажется.
← →
Компромисс (2011-09-09 13:30) [200]А в данном случае - в ответах на форуме надо стараться писать самый правильный код, потому как новички быстро схватывают, но трудно переучиваются. Прочитав впервые неправильную обработку, новичок посчитает, что это и есть тот самый способ, каким профессионалы обрабатывают исключения. Уж лучше написать комментарий "Тут должна быть обработка исключений, но мне лень ее писать" :-)
Страницы: 1 2 3 4 5 6 7 8 вся ветка
Форум: "Прочее";
Текущий архив: 2012.01.01;
Скачать: [xml.tar.bz2];
Память: 0.82 MB
Время: 0.04 c