-
Возникали споры, правомерно ли в некоторых случаях оставлять тело except пустым. Всегда находились те люди, которые утверждали, что тело пустым никогда не должно быть, ни при каких обстоятельствах, иначе это неправильно, как минимум нужно делать вывод в лог. Вот встретил в проекте хороший пример: var
Document: IHTMLDocument2;
Window: OleVariant; ... try
Window:=Document.parentWindow;
Window.before_print_script;
except ;
end; Смысл в том, что в HTML документе перед его печатью вызывается функция before_print_script (если она есть). По смыслу эту JS функция может выполнять всякие преобразования полезные (удобные) для печати. Но этой функции вполне может не быть, документ и так хорошо для печати подходит, но движок программы знать этого не может. Ну и естественно тело except пустое, потому что это даже не предупреждение, что отсутствует функция before_print_script, она в общем-то и не обязана присутствовать, просто где есть - вызывается. Но в реальности если такой функции нету, то будет сгенерировано исключение, которое молча подавляется. Все логично на мой взгляд. Или у приверженцев теории, что except низачто нельзя оставлять пустым, есть противо аргументы? Интересно.
-
По хорошему, такие ситуации надо разруливать не try-except' ом, а IF'ом IF before_print_script_Exists then ...
-
> Или у приверженцев теории, что except низачто нельзя оставлять > пустым, есть противо аргументы? Интересно.
Ты тролль ?
-
> По хорошему, такие ситуации надо разруливать не try-except' > ом, а IF'ом
ну я тоже об этом думал. Но судя по всему в данной ситуации хрен это проверишь.
-
Все равно исключение должно иметь свой тип. И исключение ловить только на вызов, где оно может возникнуть. Так что лучше написать
Window:=Document.parentWindow;
try
Window.before_print_script;
except
on E: EOleError do ;
end;
-
try adoconnection.open(); Result := True; except try adoconnection.open('user','password'); result := True; except on E:Exceptiuon do .... end; end
В контексте вопроса верхний блок - пустой. и все логично.
-
в параметрах подключения кнопка для adodb.prompdatasource и возможность ввести имя пароль.
я не знаю, какая строка подключения будет у юзера. с паролем и именем или с использованием nt аутентификации.
если без нт, я не хочу парсить ее и вставлять логин/пароль. и не хочу допустим сохранять ее в настройках с паролем.
отсюда такой двуступенчатый try/except
и пустой верхний блок
-
> Добежал (16.01.09 17:48) > Возникали споры, правомерно ли в некоторых случаях оставлять > тело except пустым
Все правомерно!!!
result:=CONST_EXCEPTION; try ........... IF WorkDoneWell then result:=CONST_OK else result:=CONST_NOT; except end;
-
> oxffff © (16.01.09 18:34) [7] > Все правомерно!!! Только кривовато немного, вот так посимпатичнее будет:
try
if WorkDoneWell then
result := CONST_OK
else
result := CONST_NOT;
except
result := CONST_EXCEPTION;
end;
> All Как показывает этот и многие другие примеры, при правильном кодинге необходимость оставлять секцию except пустой просто не возникает. :о)
-
> при правильном кодинге необходимость оставлять секцию except > пустой просто не возникает
ну тогда как "правильно" переписать пример? try
Window:=Document.parentWindow;
Window.before_print_script;
except ;
end; Ведь здесь как видно секция except пустая оказалась.
-
> Юрий Зотов © (16.01.09 19:16) [8] > > oxffff © (16.01.09 18:34) [7] > > Все правомерно!!! > > Только кривовато немного,
Кривость насколько я понял состоит в том, что обращение к result при нормальном режиме 2 раза?
> Как показывает этот и многие другие примеры, при правильном > кодинге необходимость оставлять секцию except пустой просто > не возникает. > :о)
Как показывает этот и многие другие примеры, подходов к программированию может быть не один.
try if WorkDoneWell then result := CONST_OK else result := CONST_NOT; exit; except end; result := CONST_EXCEPTION;
-
function TURSCmdMngr.OnAccUsrChangePwd2(Request: TFCGIRequest): Integer;
var
param : TFCGIParameter;
OldPwd, NewPwd : string;
begin
Result := rrDataError;
try
param := Request.FCGParams.ParamByName(wc_OldPwd);
if param=nil then Exit;
OldPwd := param.AsString;
param := Request.FCGParams.ParamByName(wc_NewPwd);
if param=nil then Exit;
NewPwd := param.AsString;
StreamWriteString(Request.InData, OldPwd, ACU_AccUsrOldPwd);
StreamWriteString(Request.InData, NewPwd, ACU_AccUsrNewPwd);
Result := rrOK;
except on E : Exception do
OnException('TURSCmdMngr.OnAccUsrChangePwd2 : ' + E.Message);
end;
end;
-
> Юрий Зотов © (16.01.09 19:16) [8] > > oxffff © (16.01.09 18:34) [7] > > Все правомерно!!! > > Только кривовато немного, вот так посимпатичнее будет: > > try > if WorkDoneWell then > result := CONST_OK > else > result := CONST_NOT; > except > result := CONST_EXCEPTION; > end;
Однако про кривость помогу так прокомментировать. При некоторых обстоятельствах(механизме информирования о результате) предварительная установка ошибки может быть более предпочтительная, чем уведомление об ошибки в момент ошибки(причем это не всегда возможно сделать сообщить об ошибке). Естественно речь идет не возврате через переменную, а например через callback процедуру.
-
> Ega23 © (16.01.09 19:33) [11] Это в защиту сабжа или против? :)
-
Так этот код > try > if WorkDoneWell then > result := CONST_OK > else > result := CONST_NOT; > exit; > except > end; > result := CONST_EXCEPTION;
равен этому result := CONST_EXCEPTION;
-
> Anatoly Podgoretsky © (16.01.09 19:48) [14]
Почему?
try raise Exception.Create('none'); if TRUE then showmessage('CONST_OK') else showmessage('NOT'); exit; except end; showmessage('EXCEPTION'); end;
Закоментируйте и раскоментируйте raise Exception.Create('none');
-
> Юрий Зотов © (16.01.09 19:16) [8] > > oxffff © (16.01.09 18:34) [7] > > Все правомерно!!! > > Только кривовато немного, вот так посимпатичнее будет: > > try > if WorkDoneWell then > result := CONST_OK > else > result := CONST_NOT; > except > result := CONST_EXCEPTION; > end;
Я в большинстве своего кода, именно так и пишу. Просто мне всегда интересно найти сходную альтернативу.
-
> Anatoly Podgoretsky © (16.01.09 19:48) [14] > > Так этот код > try
if WorkDoneWell then
result := CONST_OK
else
result := CONST_NOT;
exit;
except
end;
result := CONST_EXCEPTION;
> равен этому result := CONST_EXCEPTION;
-
А логи пишут только трусы? А обработка ошибок отменена указом президента?
-
> test (16.01.09 20:10) [18] > А логи пишут только трусы?
Нет, только майки.
-
> TURSCmdMngr.OnAccUsrChangePwd2 кризис в действии? стараетесь лишний раз не стирать клавиши на клавиатуре? :)
-
> Anatoly Podgoretsky (16.01.2009 19:48:14) [14]
Извиняюсь, рабочий, не заметил кое что, но даже в этом коде можно result := CONST_EXCEPTION; перенести выше и except будет уже не пустой, так что данный код не может быть аргументом.
-
-
> Anatoly Podgoretsky © (16.01.09 20:18) [21] > > Anatoly Podgoretsky (16.01.2009 19:48:14) [14] > > Извиняюсь, рабочий, не заметил кое что, но даже в этом коде > можно result := CONST_EXCEPTION; перенести выше и except > будет уже не пустой, так что данный код не может быть аргументом. >
Почему? + Есть например [7] с учетом [12].
-
Еще например пример из моего кода. try try ....
if TRUE then showmessage('CONST_OK') else showmessage('NOT'); except result:=const_EXCEPTION; //Делаем вещи по обработке исключения, но они могут привести к другому исключению. //или просто raise; end; except end;
Внешний пустой try\except глотает все неизвестное.
-
> oxffff (16.01.2009 20:30:23) [23]
Я про конкретный, а не про все варианты. В конкретном нет разницы между
except end; result := CONST_EXCEPTION;
и
except result := CONST_EXCEPTION; end;
И мне второй вариант приятнее, не говоря уже об верхних строках.
-
> Anatoly Podgoretsky © (16.01.09 20:46) [25]
Тогда [24], либо [7]+[12].
-
> oxffff (16.01.2009 20:45:24) [24]
Вот это другое, похоже кусок сервера или служды, но я бы не стал делать пустым, а включил бы управляемое логирование.
-
блин, народ понес свои примеры... Но все таки, господа, я бы хотел рассмотреть свой пример :)) Если код: try
Window:=Document.parentWindow;
Window.before_print_script;
except ;
end; Неправильный в силу нарушения... эээ... так сказать "паттерна проектирования" что нельзя тело except оставлять пустым, то что же тогда должно быть здесь в теле except?
-
> Anatoly Podgoretsky © (16.01.09 20:54) [27] > > oxffff (16.01.2009 20:45:24) [24] > > Вот это другое, похоже кусок сервера или служды, но я бы > не стал делать пустым, а включил бы управляемое логирование. >
Я естестенно пишу, как [7],[8],[10],[24] в зависимости от ситуации. Я придерживаюсь простой для меня истины, есть разные способы решения. Но не один.
-
> Неправильный в силу нарушения... эээ... так сказать "паттерна > проектирования" что нельзя тело except оставлять пустым, > то что же тогда должно быть здесь в теле except?
Посылай с такими утверждениями на .... Думай своей головой.
-
> Добежал (16.01.09 21:01) [28]
Я уже отвечал в > Mystic © (16.01.09 18:06) [4]. В теле except должно быть тип исключения, который ты хочешь игнорировать.
-
догматизм это не есть хорошо )
-
Eraser © (16.01.09 21:20) [32] Хаскел изучаем?
oxffff © (16.01.09 20:45) [24] У тебя произошла ошибка неизвестно где и программа продолжила свой ход, если это Hello world да и черт с ним, если что то сложнее то что то надо делать кроме ;
-
> Добежал (16.01.09 17:48)
программа будет тихо не открывать документ. на первый, второй, третий, N-й раз, пока юзер не выйдет из себя и: 1. не выкинет программу в корзину 2. не напишет гневный мейл/звонок/тираду на совещании А если б except вообще бы не было, был был вопль в рабочем порядке, и проблема решилась бы if`ом. Ясное дело, что проблема не в юзерах и не в except, а в трансляции OLE-ексептиозов в дельфайные
-
> Ганя (16.01.09 17:51) [1] > > По хорошему, такие ситуации надо разруливать не try-except' > ом, а IF'ом > IF before_print_script_Exists then ...
try except для того и придуман в частности, чтобы не плодить эти самые if then и не захламлять ими код. Место возникновения ошибки отделено от места ее обработки.
Так что хочешь try..except хочешь if then, хочешь их вместе. Все едино. Кому как нравится.
Лично я не вижу ничего зазорного в пустом except. Или в таком:
try n := strtoint(s); except n := 0; end;
-
Да "все банально до тривиальности". Программист "А" пишет плохой "код А": try
Window:=Document.parentWindow;
Window.before_print_script;
except ;
end; Через пару месяцев программист "Б" пишет плохой "код Б", дорабатывая "код А": try
Window:=Document.parentWindow;
Window.adjust_print_script;
Window.before_print_script;
except ;
end; Через неделю программиста "А" заставляют искать ошибку в его методе печати из-за жалоб разгневанных пользователей, потому что adjust_print_script тоже может не быть, и печать не работает. Ну и ясен пень, "виноват программист Б"?.. При написании кода нужно добавлять еще одно измерение - Время. Или придерживаться принципа - подтер себе, убери за товарищем?.. Впрочем, такой код можно писать, если после компиляции исходники уничтожаются - и писать просто, и поддерживать не нужно.
-
Владислав (16.01.09 22:21) [36] Вот ты счас серьезно или ради красного словца?
-
Владислав (16.01.09 22:21) [36]
> Впрочем, такой код можно писать, если после компиляции исходники > уничтожаются - и писать просто, и поддерживать не нужно. >
Исходники надо уничтожать всегда. Иногда лучше до написания
-
> test (16.01.09 21:48) [33] > > oxffff © (16.01.09 20:45) [24] > У тебя произошла ошибка неизвестно где и программа продолжила > свой ход, если это Hello world да и черт с ним, если что > то сложнее то что то надо делать кроме ;
Ты внимательно код смотрел?
Значит давай разберем.
У тебя есть некоторые операции, которые могут привести к исключению и детерминированно установить такой исход ты не в состоянии. Однако есть требование не вылетать при этой операции. И логировать кривой ее исход. При противодействии исключению операции, логированиии, ты же понимаешь, что противодействии исключению, логирование - это такая же операция, как и другие, и она также может вызвать исключение. Особенно, если код делегирован некоторому контракту(логирование в файл, логирование в БД, логирование по E-mail).
Тогда ты делаешь так.
try try ....
if TRUE then showmessage('CONST_OK') else showmessage('NOT'); except result:=const_EXCEPTION;
//Здесь ты противодействуешь исключению, пытаешься восттановить состояние, логируешь кривой исход операции. //или просто raise; end; except //Это для того, когда ничего не помогло, а работать надо дальше. end;
Теперь тебе понятно?
P.S. Только приехал с больнички, ездил обогреватель отвозил, у нас -30.
-
oxffff © (16.01.09 22:50) [39] Ошибка она видимо неустранимо в принципе? Логирование оно не может работать в принципе? Не стандартные ситуации не предсказуемы?
-
> test (16.01.09 22:58) [40] > oxffff © (16.01.09 22:50) [39] > Ошибка она видимо неустранимо в принципе? Логирование оно > не может работать в принципе? Не стандартные ситуации не > предсказуемы?
Именно так. Ошибка не известна(либо намеренно игнорирована) и поэтому не устранима. Если у тебя есть только контракт по логированию, реализация тебе не известна, подключается run time, но тебе нужно обеспечить нормальное продолжение после операции(возможно даже не известной).
> Ошибка она видимо неустранимо в принципе?
Да, если она не известна.
> Логирование оно не может работать в принципе?
Да, если логирование через делегат.
Не стандартные ситуации не предсказуемы?
Безусловно.
-
> test (16.01.09 22:39) [37] > Владислав (16.01.09 22:21) [36] > Вот ты счас серьезно или ради красного словца?
Я серьезно. А ты просто так спросил, чтобы флейм разводить, или протестировать? :)
> Игорь Шевченко © (16.01.09 22:45) [38] > Владислав (16.01.09 22:21) [36] > > > > Впрочем, такой код можно писать, если после компиляции > исходники > > уничтожаются - и писать просто, и поддерживать не нужно. > > > > > > Исходники надо уничтожать всегда. Иногда лучше до написания
Игорь, это была шутка, сарказм, или еще что-то? Я не понял :)
-
> Лично я не вижу ничего зазорного в пустом except. Или в > таком:
Зазорно/не зазорно, но многим приходилось вылавливать ошибки других из-за try ... except end; Так что эти грабли есть. Конечно, в приведенном тобой коде трудно представить себе ошибку. Но если s это поле класса, который по непонятным причинам в этот момент уже nil, программа будет работать как ни в чем не бывало и выдавать результат 0. Это несколько сбивает с толку, потому что процесс поиска направлен в сторону нахождения момента, где в поле s записывается нецелое число. Подобные ситуации были в моей практике неоднократно. Мне непонятно, почему нельзя добавить всего одну строку и избежать таких проблем?
try
n := strtoin(s);
except
on E: EConvertError do
n := 0;
end;
-
> Mystic © (16.01.09 23:35) [43] > > > Лично я не вижу ничего зазорного в пустом except. Или > в > > таком: > > > но многим приходилось вылавливать ошибки > других из-за try ... except end;
Что ошибки вылетали из такого?
try //Do something very wrong. ... except //пусто end;
-
> try > n := strtoin(s); > except > on E: EConvertError do > n := 0; > end;
Такого рода решение зависит от поставновки задачи. А именно
1. Устанавливать значение по умолчанию 2. или бить тревогу. 3. Ведь может же быть что-то другое.
-
> Mystic © (16.01.09 23:35) [43]
Конечно же к такому использованию try except надо подходить с умом. Т.е. если уж пустой оставляешь, то с гарантией, что проблем далее не возникнет. Ведь гораздо проще подавить к чертям исключение, особенно когда знаешь, что возникнуть может только оно и никакое другое, чем колупаться с on E: и т.д.
> Мне непонятно, почему нельзя добавить всего одну строку > и избежать таких проблем?
Лень, скорее всего.
А пустой try except встречается постоянно у многих. И борланд тоже этим грешит.
-
> Что ошибки вылетали из такого?
Из такого они не вылетали, из такого они только накапливались. И долго не находились.
-
> Mystic © (16.01.09 23:42) [47] > > Что ошибки вылетали из такого? > > Из такого они не вылетали, из такого они только накапливались. > И долго не находились.
Как раз именно ваш код позволяет их долго не находить. Согласно вашего кода, любые входные параметры s корректны. Не может быть ситуации и поэтому она просто не обрабатывается, когда входной параметр не корректен. Более того, если пользователь например ввел 1223O333, что визуально корретна, программа проглотит без вопросов. Однако пользователь увидит не тот результат, который должен быть для 12230333.
А управляемая ракета полетит мимо. :)
Это вопрос постановки задачи.
Ведь накапливались из-за этого самого вашего кода. :)
Ваш код говорит, что ошибок в принципе нет.
-
> Mystic © (16.01.09 23:42) [47]
Естественно я никак не хочу, как то дискредитировать это решение. Я просто подвожу всех и себя к мысли, что нельзя сказать именно так хорошо и никак иначе. :)
-
> oxffff © (16.01.09 23:52) [48]
> Согласно вашего кода, любые входные параметры s корректны. >
это скорее обо мне :)
-
> А пустой try except встречается постоянно у многих. И борланд > тоже этим грешит.
Пустой try...except имеет свой смысл. Обычно применяется там, где надо выполнить некоторую второстепенную последовательность действий абсолютно не заботясь о результате. Например, записать в лог строку. Тут мы хотим гарантировать, чтоб какой кошмар там не случился, но программа бы не завалилась.
-
> [41] oxffff © (16.01.09 23:10)
давайте тогда каждую строку оборачивать в try..except и на заносить отчет об ошибке в лог, в случае чего. все исключения (в т.ч. обработанные) логировать полезно, но централизовано, с помощью спец. средств. в данном случае вполне достаточно try
Window.adjust_print_script;
except
end; благо такие случаи редкость.
-
> Eraser © (16.01.09 23:59) [52] > > [41] oxffff © (16.01.09 23:10) > > давайте тогда каждую строку оборачивать в try..except
Это уже параноидальный подход. Достаточно защищить только опасный или неизвестный код, который может привести к другому потоку программы, и когда именно определенный поток действий программы должен соблюдаться не смотря ни на что.
-
> Mystic © (16.01.09 23:42) [47] > > Что ошибки вылетали из такого? > > Из такого они не вылетали, из такого они только накапливались. > И долго не находились.
Естественно, но нужно же устанавливать некий признак неудачи и проверять для продолжения дальнейших действий. Я уверен мы все все понимаем. А от темы мы уже ушли, как всегда. :)
Вопрос может ли быть полезен пустой код except?
Мой ответ - ДА.
А Ваш?
-
> Вопрос может ли быть полезен пустой код except?
Может быть в редких случаях. Пример такого случая я уже обрисовал.
-
> Mystic © (17.01.09 00:23) [55] > > Вопрос может ли быть полезен пустой код except? > > Может быть в редких случаях. Пример такого случая я уже > обрисовал.
Уже 2 голоса ЗА!!! :)
-
> Может быть в редких случаях.
Я бы сформулировал несколько по иному. Есть ряд случаев, где пустой код except категорически недопустим!
-
Владислав © (16.01.09 23:20) [42]
> Игорь, это была шутка, сарказм, или еще что-то? Я не понял > :)
Скорее пожелание авторам :)
-
> Скорее пожелание авторам :)
Тем, которые ратуют за право использовать пустой код except о)
-
Вот, помнится, Рихтер, при разборе сообщений системного журнала рекомендовал заворачивать вызов FormatMessage в блок обработки исключений а исключения игнорировать... А там вылезти может все что угодно, вплоть до Access violation.
-
> oxffff (17.01.2009 0:25:56) [56]
Я за то, что солнце встает на западе, кто ЗА
-
> vuk © (17.01.09 01:10) [60] > > Вот, помнится, Рихтер...
Не понял. Это пост ЗА или ПРОТИВ? :)
-
to Германн © (17.01.09 01:30) [62]: А чего непонятного-то? Ну бывают случаи, когда на исключение нужно забить. И если это действительно нужно, то я не понимаю, зачем делать догму из наличия кода в обработчике.
-
> vuk © (17.01.09 01:35) [63] > > to Германн © (17.01.09 01:30) [62]: > А чего непонятного-то? Ну бывают случаи, когда на исключение > нужно забить.
Да я-то понял. Но Рихтер не дельфист. (Не. Кто-то из мастеров, по-моему я знаю кто, написал в шутку, что Рихтер "пишет книгу по Дельфи, но "в стол""). Но в Дельфи немного другая ситуация. Дельфи - это в первую очередь RAD-система рассчитанная на использование компонент. А вот уже при написании компонент такой подход недопустим ни в коем случае!
-
to Германн © (17.01.09 01:43) [64]: >Да я-то понял. Но Рихтер не дельфист. А какая разница-то, на чем писать код игнорирующий исключения?
>Дельфи - это в первую очередь RAD-система Это средство программирования. И задачи разные бывают. Я, вот, системный журнал парсил.
-
> vuk © (17.01.09 01:46) [65] > > to Германн © (17.01.09 01:43) [64]: > >Да я-то понял. Но Рихтер не дельфист. > А какая разница-то, на чем писать код игнорирующий исключения? > >
Вот я лично нарвался на серьёзную проблему при использовании стороннего компонента, в котором в одном из методов был тот самый пустой блок except. Программа моя вылетала молча. А я никак не мог понять почему! P.S. Я уже не первый раз на этом форуме об этом конкретном случае говорю. И автор сего компонента - весьма уважаемый среди дельфистов. (По времени своего появления сравним с автором QR. По своей грамотности - гораздо выше). А что знает Джеффри про некие компоненты?
-
to Германн © (17.01.09 02:05) [66]: >Вот я лично нарвался на серьёзную проблему при использовании >стороннего компонента, в котором в одном из методов был тот самый >пустой блок except.
Ну написал кто-то кривой компонент. Так ведь из кривизны конкретного компонента вовсе не следует, что обработчик должен быть пустым или не пустым. Потому что с равной вероятностью обработчик может быть написан так, что будет приводить к неверному функционированию.
>А что знает Джеффри про некие компоненты? А зачем оно ему? Он книжку писал про разработку под W2K. А уж на чем писать, тут разницы нет.
-
> vuk © (17.01.09 02:18) [67] > > to Германн © (17.01.09 02:05) [66]: > >Вот я лично нарвался на серьёзную проблему при использовании > >стороннего компонента, в котором в одном из методов был > тот самый > >пустой блок except. > > Ну написал кто-то кривой компонент. Так ведь из кривизны > конкретного компонента вовсе не следует, что обработчик > должен быть пустым или не пустым. Потому что с равной вероятностью > обработчик может быть написан так, что будет приводить к > неверному функционированию.
-
Случайно нажал "Добавить".
В методе того компонента был тот самый пустой блок except. Но в том методе вызывался пользовательский обработчик. Так вот ошибка была именно в нём. Я ожидал, что, если будет ошибка, то будет и сообщение об ощибке! Ан нет.
-
vuk © (17.01.09 02:18) [67]
> >А что знает Джеффри про некие компоненты? > А зачем оно ему? Он книжку писал про разработку под W2K. > А уж на чем писать, тут разницы нет.
В стол :)
А если по теме, то можно использовать и пустой блок except end и goto, Аллах простит. И компилятор откомпилирует без хинтов и предупреждений.
Хотя лично я за то, что если в программе ошибка, то пусть она вылетает с максимально громким треском - ее найти при этом проще.
-
> Игорь Шевченко © (17.01.09 03:06) [70] > > vuk © (17.01.09 02:18) [67] > > > > >А что знает Джеффри про некие компоненты? > > А зачем оно ему? Он книжку писал про разработку под W2K. > > > А уж на чем писать, тут разницы нет. > > > В стол :)
В стол. Не. Ну это не ты первый упомянул сей термин, зафиксированный в Орешнике! Или ты? В общем-то без разницы, лишь ради исторической справедливости.
-
Игорь Шевченко © (17.01.09 03:06) [70] Не обязательно вылетать, часть ошибок можно обработать.
oxffff © (17.01.09 00:09) [54] Тебе дадут на сопровождение прогу которая писалась 5 лет назад с пустыми исключениями, может тогда поймеш в чем зло этого подхода.
-
test (17.01.09 08:40) [72] +1
Кстати хотелось бы увидеть пример и описание условий в которых может произойти ЛЮБОЕ исключение и нельзя написать on E:Tконкретный класс исключений ;
-
Вот раздули.... :) Какая разница пустой блок или не пустой, нужно писать грамотно и с трезвой головой с учетом на будущее, а там не важно как ты пишешь.... или хотите сказать так не бывает? Бывает.
-
> test (17.01.09 08:40) [72]
Не нужно перегибать палку. Я привел пример, когда это востребовано и оправдано. А ты пытаешься перефразировать мои слова на свой лад.
>Sergey Masloff (17.01.09 10:52) [73]
Есть мой многопоточный планировщик запуска некоторых заданий в зависимости от изменений в файловой системе. Если мне не изменяет память построен на IOComplentionPort. Причем само задание и логирование его исполнения - это ислючительно контракт. Итак упрощенно есть ITask, ILog.
Cхема у меня в реальном проекте на несколько уровней try больше. Упрощено так.
try ILog.Infrom('Task Start'); try ITask.Start; except ILog.Infrom('Task Error'); raise; end; ILog.Infrom('Task End'); except //Попадаем сюда в случае сбоя ILog или при сбоя ITask. end;
-
oxffff © (17.01.09 11:46) [75] То есть никто у тебя не стартовал, лог тоже сбойнул никто про это не узнал все хорошо. Спасибо, следующий ;-)))
-
> Sergey Masloff (17.01.09 11:53) [76] > oxffff © (17.01.09 11:46) [75] > То есть никто у тебя не стартовал, лог тоже сбойнул никто > про это не узнал все хорошо. Спасибо, следующий ;-)))
Ты что глупый?
Во первых >Cхема у меня в реальном проекте на несколько уровней try больше.
В главных
Лог это возможность информировать пользователя. Если он сбойнул, то этой возможности нет.
-
> Sergey Masloff (17.01.09 11:53) [76]
Ты слышал про Double Fault?
-
> Sergey Masloff (17.01.09 11:53) [76]
На самом деле у меня ILog.Infrom('Task Start') тоже оборачиваются. Но я специально упростил, чтобы было понятней.
-
oxffff © (17.01.09 11:59) [77] Я все понял. Программа не работает но внешне все хорошо. Повторяю спасибо, мне слышать больше ни о чем не надо.
-
> Sergey Masloff (17.01.09 12:05) [80]
Ты внимательно смотрел код? Это код кода отдельного потока, который запускает неизвестное ему задание, и логирует неизвестно куда.
-
> Повторяю спасибо, мне слышать больше ни о чем не надо.
Мне жаль что ты совершенно не внимательно прочитал мои посты.
Вот упрощенный код общего запуска и логирования.
procedure DoTask(const Task:ITask;const Log:ILog); begin try Log.Inform('Task Start'); except end; try try Task.Start; except try Task.TryToCloseTask; except end; Log.Inform('Task Error'); raise; end;
try Log.Inform('Task End'); except end; except end; end;
-
oxffff © (17.01.09 12:36) [82] Что будет если Log.Inform('Task Start'); свалиться в ошибку, а потом Task.TryToCloseTask;. Память бесконечно, как и процессорное время?
-
> test (17.01.09 12:44) [83] > oxffff © (17.01.09 12:36) [82] > Что будет если Log.Inform('Task Start'); свалиться в ошибку, > а потом Task.TryToCloseTask;. Память бесконечно, как и > процессорное время?
Этот вопрос нужно не мне задавать, а тому кто будет писать Log и Task. В этом коде не видно, однако и Log и Task будут разрушены тоже безопасностно. Задача это кода гарантровать работостопосбность центрального приложения, которое запускает неизвестное задание и пишет в неизвестный лог. Что касается возможных потерь внутри кода Log и Task - это вопросы к его разработчику.
-
test (17.01.09 08:40) [72]
> Не обязательно вылетать, часть ошибок можно обработать.
Есть два вида ошибок - ошибки из-за неверных данных и ошибки алгоритма.
Первые надо обрабатывать (возможно), о вторых надо как можно громче сообщать. То есть, для примера, если кто-то ввел вместо 11234 112ЗЧ то это стоит обработать и позволить ввести верное значение. А если в результате действий программиста произошло обращение к неинициализированному указателю, то стоит вылететь с максимально громким треском.
-
-
> Anatoly Podgoretsky © (17.01.09 13:25) [86] > > Sergey Masloff (17.01.2009 11:53:16) [76] > > Намекаешь на http://www.podgoretsky.com/OtherParts/DM/BadWill. > aspx пукт 4?
Есть глубокая уверенность, что и вы тоже не внимательно прочитали мои посты. Специально для Вас: Если нет 100% уверенности, что внешний код не может генерировать исключение(ввиду ошибки его автора и природа этих ошибок не известна), то необходимо создавать максимально robust центральное приложение устойчивое к такого рода воздействиям. Если рассуждать по вашему. То есть например плагин 3D max, который сгенерировал неизвестное исключение, что теперь вся среда должна киркнуться? Так по вашему? P.S. Я предлагаю добавить еще один пункт в ваши вредные заветы первым. Оказание вредных советов без понимания сути.Наказание: на кол.
-
> Anatoly Podgoretsky © (17.01.09 13:25) [86] > > Sergey Masloff (17.01.2009 11:53:16) [76]
Есть зоны ответственности за исключение.
-
> oxffff © (17.01.09 13:43) [88] > > Anatoly Podgoretsky © (17.01.09 13:25) [86] > > > Sergey Masloff (17.01.2009 11:53:16) [76] > > Есть зоны ответственности за исключение.
А это означает, что на определенных уровнях все неизвестные исключения должны "проглатываться", чтобы не нарушить функциональность вызывающей части.
-
> oxffff (17.01.2009 13:40:27) [87]
Создание robust приложений и пустые except end - как бы не связаны или наоборот.
-
> oxffff (17.01.2009 13:47:29) [89]
Ну и как это связано с пустой/не пустой try except. По твоим словам вытекает, что только пустой проглотит, а не пустой нет. Даже вывод диалога в try except не влияет на это, отлично проглатывается. Эти критерии не подходят, найди что ни будь другое.
-
> Anatoly Podgoretsky © (17.01.09 13:51) [90]
Не внимательно читали?
Если нет 100% уверенности, что внешний код не может генерировать исключение(ввиду ошибки его автора и природа этих ошибок не известна), то необходимо создавать максимально robust центральное приложение устойчивое к такого рода воздействиям.
Поэтому есть [88] с пояснением [89].
Я жду ваш ответ про плагины к средам.
-
> Anatoly Podgoretsky © (17.01.09 13:53) [91] > > oxffff (17.01.2009 13:47:29) [89] > > Ну и как это связано с пустой/не пустой try except. По твоим > словам вытекает, что только пустой проглотит, а не пустой > нет. Даже вывод диалога в try except не влияет на это, отлично > проглатывается. Эти критерии не подходят, найди что ни будь > другое.
Покажите мне код, который обрабатывает неизвестное исключение.
Рассмотрим пример [82]. Есть необходимость запускать что-то и логировать куда-то. И там и там есть потенциальное уязвимое место. Поэтому есть зона ответственности по приоритетам.
1. логика центрального приложения 2. Логика запуска внешнего задания 3. Логика логирования.
Если мы не защитим 3, мы нарушим 2. что недопустимо.
Поэтому
try Log.Inform('Task Start'); except end;
Ошибка логирования не должна не позволить запустить задание. Если мы не защитим 2, мы нарушим 1, что недопустимо. Если мы пропустим за
except end; end;
Мы нарушим логику центрального приложения.
-
> Покажите мне код, который обрабатывает неизвестное исключение.
except
on E: Exception do ErrorDialog(E.Message, E.HelpContext);
end;
-
> Anatoly Podgoretsky © (17.01.09 14:10) [94] > > > Покажите мне код, который обрабатывает неизвестное исключение. > > > except > on E: Exception do ErrorDialog(E.Message, E.HelpContext); > > end;
Этот диалог никто не увидит. Я еще раз повторяю, что любое информирование для пользователя ведется через ILOG задачи. Если он сбойнул, мы должны защититься.
+дополнительный вопрос. А где гарантии что ErrorDialog сам не вызовет исключение, нарушив логику?
Давайте я поясню работу этого приложения. Есть центральное приложение, которое отслеживает изменения в файловой системе. На определенные фильтры изменений настроен запуск задачи с ее логированием. И задача и логирование предоставлется плагином DLL. Пришли определенные файлики из SAP R3 запускается задачи с логированием в потоке - закачка данных в Oracle, MSSQL, foxpro, Аcesss.
-
> Anatoly Podgoretsky © (17.01.09 14:10) [94]
Где ответ на
>Я жду ваш ответ про плагины к средам.
-
> oxffff (17.01.2009 14:22:35) [95]
Не уходи от темы, тебе нужна была обработка любого, заранее неизвестного исключения, теперь ты придераешься к форме. Не нравится ErrorDialog замени на ErrorLog или на что хочешь, на твое любимое.
-
"если в программе ошибка, то пусть она вылетает с максимально громким треском" (с) [70]
Конечно, здесь Игорь имел в виду ошибку программы, а не юзера.
И этим все сказано. Других аргументов не требуется. А если кто в этом сомневается, то перестанет сомневаться как только ему "дадут на сопровождение прогу которая писалась 5 лет назад с пустыми исключениями" (с) [72].
Молчаливое гашение ошибок программы - ОЧЕНЬ дурной стиль. Возможно, что действительно (хотя и крайне редко) встречаются ситуации, когда на это все же приходится идти, но в каждом конкретном случае обязательно нужно проанализировать, почему такая ситуация возникла и приложить максимум усилий для того, чтобы ее избежать. Вплоть до перепроектирования кода.
И это вовсе никакая не догма, а суровая правда жизни. Если прыгнуть с 20-го этажа, то разобьешься (хотя мизерный шанс все же есть). Все об этом знают и не прыгают. И догмой не называют.
Но спор бессмысленен. Потому что это спор тех, кто уже успел понабивать шишек с теми, кто еще понабивал их недостаточно. И пока не понабивают достаточно, все равно не поймут.
-
Юрий Зотов © (17.01.09 15:35) [98]
Я в [85] раскрыл тему :)
-
Ок. Вываливаться с треском. Ситуация. При форматировании сообщения и EventLog получилось так, что приложение, добавившее запись, свалило туда полную ахинею и при форматировании вылетает Access Violation. Что делать-то, вываливаться с криками "Нас обманули!" или таки удушить этот AV и продолжить разбор записи из лога дальше?
-
> vuk (17.01.2009 16:17:40) [100]
Сообщить об этом, а не в тихаря, делать вид, что все хорошо прекрасная маркиза.
-
> Молчаливое гашение ошибок программы - ОЧЕНЬ дурной стиль.
Я часто создаю собственные Exception и перехватываю их в других местах программы. Да я гашу их, - т.е. не показывают юзеру - а юзеру это и не надо. Можно возвращать ошибку через функцию, но удобнее через exception. Кто сказал что так делать нельзя?
-
> Кто сказал что так делать нельзя?
Как раз наоборот.
-
to Anatoly Podgoretsky © (17.01.09 16:37) [101]: >Сообщить об этом, а не в тихаря, делать вид, что все хорошо прекрасная >маркиза. Кому нужно это сообщение, если интересует, что находится в логе, а не накосячило ли приложение при записи туда.
Кстати. Кто-нибудь когда-нибудь наблюдал, что делают системные утилиты при разборе логов? Они именно пропускают ошибочные части сообщений и продолжают разбор. И никому ничего лишнего не сообщают.
-
vuk © (17.01.09 16:42) [104]
> Они именно пропускают ошибочные части сообщений и продолжают > разбор. И никому ничего лишнего не сообщают.
Сообщают. Как минимум, о том, что не смогли разобрать.
-
> vuk ©
1. Это ошибка данных, а речь шла об ошибках программы.
2. Что делать - зависит от того, какая это программа. Если ошибки в логе критичны, то надо вываливаться с треском. Иначе, если программа интерактивная, то можно где-нибудь (например, в статусбаре) уведомить юзера, что лог будет показан не весь и продолжать его разбор. Если же программа неинтерактивная, то аналогичное уведомление она может, например, записать в свой собственный лог и тоже продолжить разбор. И т.д.
3. Системные утилиты - штука хорошая, но их тоже пишут люди.
> Кто б сомневался © (17.01.09 16:38) [102] > Кто сказал что так делать нельзя?
Никто не говорил. И Вы не гасите ошибки, а обрабатываете их. Так делать не только можно, но и нужно (когда это возможно, конечно).
-
to Игорь Шевченко © (17.01.09 16:52) [105]: >Сообщают. Как минимум, о том, что не смогли разобрать. Это, обычно, если сообщение целиком не смогли достать. В некоторых случаях ты можно пронаблюдать в тексте сообщения сроки вида %123. То есть не смогли достать и оставили как было. И сообщений об ошибке там не будет.
-
> Anatoly Podgoretsky © (17.01.09 15:20) [97] > > oxffff (17.01.2009 14:22:35) [95] > > Не уходи от темы, тебе нужна была обработка любого, заранее > неизвестного исключения, теперь ты придераешься к форме. > > Не нравится ErrorDialog замени на ErrorLog или на что хочешь, > на твое любимое.
Вы не внимательно читаете. Логирование задания происходит через контракт с внешней реализацией. Логирование идет через ILOG. У меня нет внутреннего логирования. Мне не нужен ErrorDialog, у меня эта ситуация обрабатывается в
procedure DoTask(const Task:ITask;const Log:ILog); begin try Log.Inform('Task Start'); except end; try try Task.Start; except try Task.TryToCloseTask; except end; Log.Inform('Task Error'); raise; end;
try Log.Inform('Task End'); except end; except end; end;
Вы мне пытаетесь втюхать внутренее логирование программы,его нет. я вам в четвертый раз повторяю. Что логирование через внешнюю реализацию-интрефейс. А если так, то значит если возникло исключение при выполнении задания, то мы вызываем логирование, а поскольку оно внешее(ну нет реализации внутреннего логирования), то в нем может произойти исключение(нет места, обрыв соединения и т.д., отказ от... т.е. совершенно произвольное исключение, которое еще объявлено во внешней программе). Поэтому само логирование тоже нужно защитить пустым except end;
Я надеюсь теперь вам понятно или опять как в [14] и [15]?
Да и ответьте на вопрос, что должна делать среда, если в одном из ее плагинов произошло исключение, пропускать ее дальше, если она не знает его природу(т.е. чтобы приложение рухнуло) и все таки гасить при переходе в другую зону ответственности. Вы боитесь отвечать на этот вопрос?
-
to Юрий Зотов © (17.01.09 16:57) [106]: >Это ошибка данных, а речь шла об ошибках программы. Юр, это ошибка чужих данных, результат которой приводит к AV в моей программе, но заствить другую софтину писать в лог правильно я не могу. Могу только обработать возникающие ошибки (иногда задавив исключения). При этом запись из лога должна быть показана настолько, насколько удалось вытянуть информацию.
>Иначе, если программа интерактивная, то можно где-нибудь (например, в >статусбаре) уведомить юзера, что лог будет показан не весь и продолжать >его разбор. В том-то и дело, что лог должен показываться весь. А то, что сообщение не смогли отформатировать, это иногда вставляется в сообщение, иногда нет и в этом случае часть сообщения, которую не удалось достать, остается без изменений .
-
> vuk (17.01.2009 16:42:44) [104]
Так тож логи, задача строго протиположная. Но можно и сообщить, в виде строчки, что часть лога повреждена, но там и блок особо не нужен.
-
Юрий Зотов © (17.01.09 16:57) [106] Игорь Шевченко © (17.01.09 16:52) [105]
Уважаемые, ответьте мне на вопрос [108] последний абзац. Только не забывайте в моем случае сама операция логирования внешняя ILOG, и нет никакого внутреннего логирования. Что делать, если при логировании возникло исключение, и программа работает в фоновом режиме(нет GUI). Пользователь видит все операции только через ILOG(внешний). Заранее благодарен.
А то вы предлагаете пропустить это исключение дальше, нарушив просто все, завалив среду и все другие задания. Как вы говорите с треском.
-
> vuk © (17.01.09 17:10) [109] > лог должен показываться весь.
Так и покажи его весь. В каком виде сможешь, в таком и покажи. Но нужно каким-то образом уведомить юзера о том, что в логе есть ошибки. Это и будет нормальной обработкой исключений, а не их молчаливым гашением.
-
> vuk © (17.01.09 17:10) [109] > to Юрий Зотов © (17.01.09 16:57) [106]: > >Это ошибка данных, а речь шла об ошибках программы. > Юр, это ошибка чужих данных, результат которой приводит > к AV в моей программе, но заствить другую софтину писать > в лог правильно я не могу. Могу только обработать возникающие > ошибки (иногда задавив исключения). При этом запись из лога > должна быть показана настолько, насколько удалось вытянуть > информацию.
Они этого не понимают или не видят. Я уже 3 страницы пытаюсь объяснить нашим уважаемым, но что пока не получается.
-
> Но нужно каким-то образом уведомить юзера о том, что в логе > есть ошибки.
Опять за свое. Нет никакого внутреннего логирования.
-
> oxffff © (17.01.09 17:14) [111]
> Что делать, если при логировании возникло исключение, и программа > работает в фоновом режиме(нет GUI).
Зависит от того, что это за программа и что она делает. Если вываливаться нельзя, то, возможно, о внутреннем логировании как раз и стоит подумать.
Но не делать вид, что все хорошо, когда не все хорошо.
-
> oxffff (17.01.2009 17:14:51) [111]
Ну пошли письмо.
-
> oxffff
1. Сдержанность и вежливость - достоинства, а не пороки.
2. Есть одно хорошее правило - критикуй не оппонента, а его точку зрения.
3. Подумайте о том, что и Вам тоже пытаются объяснить, тоже на 3-х страницах и тоже не получается.
-
Юр, не надо меня агитировать за обработчики исключений. Я их сам всегда пишу. И этот случай с логом - чуть ли не единственный (других вообще не помню), когда я исключения удавил. Там просто алгоритм такой был, что при возникновении ошибок функция должна была вернуть пустую строку, ну так она была в Result прописана с самого начала и исключение можно было давить.
На самом деле меня больше убивает то, что многие так пишут, будто ошибок вообще не может быть. Автор FastReport-а этим отличался. Не знаю как сейчас, может и исправился, но раньше водилось за ним такое.
-
oxffff © (17.01.09 17:14) [111]
Скрипач, ты что, дальтоник ? Зеленый от оранжевого отличить не можешь ?
-
> oxffff (17.01.2009 17:16:53) [113]
А та продолжай, доводы пока не убедительны.
-
> vuk (17.01.2009 17:37:58) [118]
Да многие известные авторы грешат этим, пишут очень грязный код.
-
oxffff © (17.01.09 17:17) [114] Есть множество чужих интерфейсов которые что то делают, и алгоритм с пунктами а б в г д е ж з. Теперь предположим они идут подряд. Любые ошибки гасятся, выполнение не останавливается.
а б тут не отработало в г д тут не отработало е тут не отработало ж з
То есть прога не жизне способная получается? Она работает исключительно в идеальных условиях, пока за компьютером сидит программист который это написал. Теперь допустим что прога не блокнот или еще какая нибудь иутилитка на пять минут, от работы которой зависит зп пользователя и работа, программист заранее вводит эффект непредсказуемости? А зачем?
-
> Anatoly Podgoretsky © (17.01.09 18:44) [120] > > oxffff (17.01.2009 17:16:53) [113] > > А та продолжай, доводы пока не убедительны.
Ваши впрочем совершенно не убедительны. :)
-
Удалено модератором
-
test (17.01.09 18:57) [122] То есть прога не жизне способная получается?
Я боюсь, пока одна сторона будет подразумевать скрытие принципиальных ошибок, а другая - непринципиальных, договориться им будет трудновато.
-
Virgo_Style © (17.01.09 19:29) [125] Если одна из сторон вообще не знает что это за ошибка откуда уверенность что эта ошибка - непринципиальна?
-
Совсем свежий пример: вчера пытался залогиниться на сайте demonoid.com (из ветки про много музыки). Ввожу имя и пароль, говорю submit и ничего не происходит (страница обновляется и на ней то же самое предложение залогиниться).
После того, как я вспомнил, что когда-то запретил cookies для этого сайта и убрал этот запрет, логин прошел как по маслу. На других сайтах при аналогичной ситуации появляется сообщение You must enable cookies.
К вопросу о тихом прятании ошибок.
-
> test (17.01.09 18:57) [122] > oxffff © (17.01.09 17:17) [114] > Есть множество чужих интерфейсов которые что то делают, > и алгоритм с пунктами а б в г д е ж з. Теперь предположим > они идут подряд. Любые ошибки гасятся, выполнение не останавливается. > > > а > б тут не отработало > в > г > д тут не отработало > е тут не отработало > ж > з > > То есть прога не жизне способная получается? Она работает > исключительно в идеальных условиях, пока за компьютером > сидит программист который это написал. Теперь допустим что > прога не блокнот или еще какая нибудь иутилитка на пять > минут, от работы которой зависит зп пользователя и работа, > программист заранее вводит эффект непредсказуемости? А > зачем?
Ты же опять перегибаешь палку. :)
Кто тебе сказал, что в этом случае нужно их гасить. Если составная операция состоит из части некритических подопераций, когда их ты обернешь в пустой блок, если у тебя нет никакой информации о том, что они могут генерировать. Все остальные операциии связаные между собой ты естественно сделаешь без гашения исключений. Ты понимаешь разницу между моим примером и своим. Мой
Есть некоторый контракт задания, есть некоторый контракт логера(а логер - это может быть txt, web, СУБД, mobile phone SMS ....). Есть процедура, которая должна вызвать задание и залогировать начало, окончание, провал задания. Процедура см выше.
Есть процедура, которая извлекает из очереди задания в отдельном потоке и вызывает вышеумомянутую процедуру и после делает некоторые действия.
TO ALL
Мой вопрос зачем мне пускать неизвестное исключение наружу в другую зону ответственности исключений? Где я не прав? Покажи мне как было реализовать эту часть правильно естественно вашего IMHO. А я вам покажу где косяки в вашем коде. Пойдет так?
-
> Игорь Шевченко © (17.01.09 19:46) [127]
Я не вижу вашего ответа, на вопрос, что должна делать среда, если плагин вызвал исключение, тихо умереть с треском по вашему?
-
Что то в последнее время на делфимастере в самые живые обсуждения по каким то ничтожным поводам. Раздули из мухи слона.
-
> Игорь Шевченко © (17.01.09 19:46) [127] > Совсем свежий пример: вчера пытался залогиниться на сайте > demonoid.com (из ветки про много музыки). Ввожу имя и пароль, > говорю submit и ничего не происходит (страница обновляется > и на ней то же самое предложение залогиниться). > > После того, как я вспомнил, что когда-то запретил cookies > для этого сайта и убрал этот запрет, логин прошел как по > маслу. На других сайтах при аналогичной ситуации появляется > сообщение You must enable cookies. > > К вопросу о тихом прятании ошибок.
Cовершенно не коррелирует с моим примером. Мой пример упрощенно
No GUI application
var Tasks:array[1..10] of ITask; ExternalLoger:Ilog; task:ITask; begin
............
Вы предлагаете следующий вариант
for task in Tasks do begin try task.execute; except ExternalLoger.Inform('Task Error'); end; end;
Я утверждаю что должно быть так.
for task in Tasks do begin try try task.execute; except ExternalLoger.Inform('Task Error'); end; except end; end;
-
Удалено модератором
-
Игорь Шевченко © (17.01.09 19:46) [127] Но роботает жы )))
oxffff © (17.01.09 19:56) [128] Да ты хоть как назови хоть контрактом хоть асбстрактом, если ты не отвечаеш за выполнение алгоритма и обработку ошибок, все твои контракты работают исключительно в идеальных условиях. Если пишеш для мамы на 8 марта красивую открытку так и пиши, если от этой программы хоть что то зависит переписывай не подставляй пользователя понопрасну.
зы Тебе было бы легче если бы я в твоем стиле алгоритм псевдо кодом оформил?
-
> test (17.01.09 20:14) [133]
Я извиняюсь, но пишите мягкий знак после Ш в глаголах.
-
> test (17.01.09 20:14) [133] >Если пишеш для мамы на 8 марта красивую открытку > так и пиши, если от этой программы хоть что то зависит переписывай > не подставляй пользователя понопрасну.
Слушай давай без упонимания о родителях. А то меня это очень злит.
-
DVM © (17.01.09 20:19) [134] привычка. Постараюсь.
oxffff © (17.01.09 20:20) [135] Хорошо перефразируем "чтобы одноклассникам показать красивую тулзу, то так и пиши", что злит то?
-
> test (17.01.09 20:14) [133] > oxffff © (17.01.09 19:56) [128] > Да ты хоть как назови хоть контрактом хоть асбстрактом, > если ты не отвечаеш за выполнение алгоритма и обработку > ошибок, все твои контракты работают исключительно в идеальных > условиях. Если пишеш для мамы на 8 марта красивую открытку > так и пиши, если от этой программы хоть что то зависит переписывай > не подставляй пользователя понопрасну.
Слушай ты какой то непонятливый.
Давай на пальцах.
Существуют некий общий алгоритм(может воспринимать его как generic метод), так вот конктретно указание конкретных типов, это и есть инстанцирование обобщеного метода. Его суть 10 независимых друг от друга заданий, которые нужно выполнить +обобщенный контракт логгера. По условию задачи сказано, что реализация не известна. Не известны также исключения которые они возвращают, более того реализация этих COM интерфейсов может быть написана на произвольном языке.
Мой код упрощенный снова.
for task in Tasks do begin try try task.execute; except ExternalLoger.Inform('Task Error'); end; except end; end;
Если я не поставлю это, прощай выполнение остальных заданий, поскольку логер может дать исключение(например нет подключения), о котором ты понятия не имеешь.
Перед тем, как что-то мне писать перечитай еще раз внимательно.
-
> test (17.01.09 20:22) [136] > DVM © (17.01.09 20:19) [134] > привычка. Постараюсь. > > oxffff © (17.01.09 20:20) [135] > Хорошо перефразируем "чтобы одноклассникам показать красивую > тулзу, то так и пиши", что злит то?
Я понимаю твой намек на школу, однако боюсь как бы тебе самому не пришлось заново закончить. см. [137].
-
oxffff © (17.01.09 19:57) [129]
> Я не вижу вашего ответа, на вопрос, что должна делать среда, > если плагин вызвал исключение, тихо умереть с треском по > вашему?
Ты что, скрипач, дальтоник ? Зеленого от оранжевого отличить не можешь ?
Среда должна отреагировать на ошибку, а уж умирать ей или нет, это зависит от многих факторов.
Среда Delphi, например, при ошибке в установленном компоненте может повести себя по-разному, как то:
Тихо умереть без звука.
Очутиться в состоянии ступора, когда при нажатии на кнопку ОК в окне сообщения об ошибке возникает точно такое же сообщение (а то и два).
Выдать сообщение об ошибке и после нажатия на ОК в окне этого сообщения продолжать работать до следующего использования этого компонента.
-
oxffff © (17.01.09 20:33) [137] Достал, просто скажи что пишешь, чтобы не пользоваться.
-
> Игорь Шевченко © (17.01.09 20:34) [139]
А как же громкая смерть приложениея со скрежетом? Вы же считаете, что нужно исключение пропустить вверх до среды. Это ислючение не будет обработано и среда сделает себе самоубийство.
Я вообще рекомендую не полагаться на чужой код, и даже логирование исключения оборачивать в SEH фрейм.
Теперь по теме.
Где я не прав в [137].
-
oxffff © (17.01.09 20:11) [131]
> Cовершенно не коррелирует с моим примером.
Ты явно дальтоник. Речь не идет о твоих примерах, твои примеры - это твои проблемы. Тебе уже который пост объясняют, что все зависит от типа ошибки - есть ошибки в данных и есть ошибки в программе. Впрочем, если из-за ошибки в данных дальнейшая работа программы не имеет смысла или потенциально приведет к каскадным ошибкам, то чем скорее впрограмма завершится с громким треском, тем лучше. Хороший пример - остановка операционной системы Windows из-за ошибки в режиме ядра, казалось бы, чего проще - выгрузи сбойный драйвер и продолжай работать, как ни в чем не бывало. Однако грамотные программисты Microsoft предпочитают останавливать систему с выдачей диагностики в виде синего экрана.
-
oxffff © (17.01.09 20:38) [141]
> Где я не прав в [137].
Я тебе последний раз говорю - есть ошибки в программе и есть ошибки в данных. Всякого рода плагины можно рассматривать как данные.
-
> Игорь Шевченко © (17.01.09 20:39) [142] > oxffff © (17.01.09 20:11) [131] > > > > Cовершенно не коррелирует с моим примером. > > > Ты явно дальтоник. Речь не идет о твоих примерах, твои примеры > - это твои проблемы. Тебе уже который пост объясняют, что > все зависит от типа ошибки - есть ошибки в данных и есть > ошибки в программе.
Да не дальтоник я. Просто нужно говорить прямо и не водить за нос.
Я бы добавил что еще есть ошибки внешние, суть которых установить не представляется возможным. Это именно те о которых я пишу в своих примерах. Добавьте в свою классификацию.
-
> Игорь Шевченко © (17.01.09 20:41) [143] > oxffff © (17.01.09 20:38) [141] > > > > Где я не прав в [137]. > > > Я тебе последний раз говорю - есть ошибки в программе и > есть ошибки в данных. Всякого рода плагины можно рассматривать > как данные.
Нельзя брить всех одинаково. от этого
-
> test (17.01.09 20:35) [140] > oxffff © (17.01.09 20:33) [137] > Достал, просто скажи что пишешь, чтобы не пользоваться.
Ты либо глуп , либо и в правду не хочешь вникать в суть и решил отделаться только общими фразами.
-
oxffff © (17.01.09 20:43) [144]
Нету внешних ошибок. Все ошибки делятся на две категории, которые должен исправлять программист и которые должен исправлять пользователь. На первую категорию ошибок однозначно надо реагировать вылетом с треском, на вторую - все зависит от задачи.
-
Игорь Шевченко © (17.01.09 20:49) [147] Бесполезно пока его сам по граблям не пройдет не успокоиться.
-
Игорь Шевченко © (17.01.09 20:49) [147] Бесполезно, пока сам по граблям не пройдет не успокоиться. Ошибок у него не существует блин.
-
> Игорь Шевченко © (17.01.09 20:49) [147] > oxffff © (17.01.09 20:43) [144] > > Нету внешних ошибок. Все ошибки делятся на две категории, > которые должен исправлять программист и которые должен > исправлять пользователь. > На первую категорию ошибок однозначно надо реагировать вылетом > с треском, на вторую - все зависит от задачи.
Тогда ошибка в плагине, который генерирует неизвестное исключение(вызванное например потерей соединения - а это безусловно ошибка программиста), должно приводить к вылету с треском всей среды по идеалогии, которой вы придерживаетесь.
Однако есть другая точка зрения. Есть зоны ответственности реагирования на ошибки частей приложения. И одни части должны защищать себя от ошибок других частей. И крах одних не должен приводить к краху других.
А внешние ошибки воспринимать как данные - это заниматься самообманом.
-
> test (17.01.09 20:56) [149] > Игорь Шевченко © (17.01.09 20:49) [147] > Бесполезно, пока сам по граблям не пройдет не успокоиться. > Ошибок у него не существует блин.
Ты понимаешь, что такое generic метод? Если нет учи мат. часть.
-
to Игорь Шевченко © (17.01.09 20:49) [147]: >Все ошибки делятся на две категории, которые должен исправлять >программист и которые должен исправлять пользователь. >На первую категорию ошибок однозначно надо реагировать вылетом с >треском, на вторую - все зависит от задачи. А куда относится AV при форматировании сообщений системного журнала? Эта ошибка не может быть исправлена программистом, т.к. это ошибка в информации занесенной в лог, допущенная совсем другой софтиной. И уж подавно, это не может быть исправлено пользователем.
-
> test (17.01.09 20:56) [149] > Игорь Шевченко © (17.01.09 20:49) [147] > Бесполезно, пока сам по граблям не пройдет не успокоиться. > Ошибок у него не существует блин.
Ошибки для меня существуют. И поверь, что я не отстаиваю точку зрения что except end должен быть пустым всегда. Более того я и пишу, как все мои оппоненты, либо информативные коды возвратов, либо дерево классов исключений с проверкой в except end.
Я отстаиваю точку зрения, что может быть и except end пустым (а это между прочим тема начальной беседы) и привел контректный пример. А ты насколько я понял не прочитал всей темы, влез в середину разговора и пытаешься меня убедить в том, что я пишу всегда пустой except end.
Я готов с тобой продолжить диалог, если ты внимательно узучишь [137] и дашь конкретные замечания(на которые я постараюсь ответить). Либо приведешь конр пример, соблюдая условия задачи, но тем не менее без пустого except end.
-
> DVM (17.01.2009 20:19:14) [134]
Дэти запомните, понять это нельзя Сол пишется с мягким знаком а Ось - это полосатый мухь, без мягкого знака.
(с) Анекдот
-
> vuk (17.01.2009 20:59:32) [152]
Вроде бы уже выяснили, что это ошибка данных, о которой надо сообщить и продолжить. Эта ошибка ни к каким последствиям не приводит.
-
to Anatoly Podgoretsky © (17.01.09 21:19) [155]: >Вроде бы уже выяснили, что это ошибка данных, о которой надо сообщить >и продолжить. Эта ошибка ни к каким последствиям не приводит.
Ну, вот мне тоже так казалось, но Игорь-то пишет о только двух категориях...
-
> Anatoly Podgoretsky © (17.01.09 21:19) [155]
Кому сообщить? В милицию? Если весь лог идет через этот журнал только, который возвращает неизвестные исключения. Это исключение должно быть тихо съедено, чтобы продолжить работу приложения. Или вы предлагаете на каждый лог еще лог. Таким образом повышая отказоустойчивость логирования, увеличивая количество вложенности логов.
Смотрите условие [137].
-
> oxffff (17.01.2009 21:25:37) [157]
Касательно [155] мы уже обсудили кому сообщить и как.
-
> Anatoly Podgoretsky © (17.01.09 21:28) [158]
Ну так, что нам мешает вернуться к обсуждению [137].
-
vuk © (17.01.09 20:59) [152]
> А куда относится AV при форматировании сообщений системного > журнала? Эта ошибка не может быть исправлена программистом
Как это не может быть исправлена программистом - может быть исправлена программистом. Например, вылавливанием этого AV, пардон, протоколированием его, и продолжением разбора следующей части. Стандартная категория "ошибка в данных".
oxffff © (17.01.09 20:56) [150]
> А внешние ошибки воспринимать как данные - это заниматься > самообманом.
Что такое "внешняя ошибка" по твоей терминологии ?
-
>Игорь Шевченко © (17.01.09 21:36) [160] > Что такое "внешняя ошибка" по твоей терминологии ?
Эта ошибка природу, которой установить невозможно, все генерируемые ею исключения отсутствуют в общем словаре. Но тем не менее.
\\ Реакция на ошибку определяется не ее типом(данные, программист, внешняя), а критичностью компонента в котором она произошла, и возможностью отказаться от этого компонента вовсе(присваивание значения по умолчанию, игнорирование невозвращенного результата).
-
oxffff © (17.01.09 21:44) [161]
> Эта ошибка природу, которой установить невозможно
Не понял, поясни. Электричество кончилось - это внешняя ошибка ? Альфа-частица пролетела сквозь планку памяти и вызвала распад битов - это внешняя ошибка ?
> все генерируемые ею исключения отсутствуют в общем словаре
что такое "общий словарь" ?
-
> Игорь Шевченко © (17.01.09 21:36) [160] > vuk © (17.01.09 20:59) [152] > > > > А куда относится AV при форматировании сообщений системного > > > журнала? Эта ошибка не может быть исправлена программистом > > > Как это не может быть исправлена программистом - может быть > исправлена программистом. Например, вылавливанием этого > AV, пардон, протоколированием его, и продолжением разбора > следующей части.
А как вы собстенно узнате характер исключения, если это будет для внешнего исключения и если это не СBuilder
cDelphiException = $0EEDFADE; cNonDelphiException = $0EEDFAE4; cCppException = $0EEFFACE; { used by BCB }
По связке External Exception + GetlastError? Если Error Code - 5. :) А как сделать вывод куда рыть в общем случае?
А что есть еще потенциально опасные недокументированные исключения внешних компонент? Не считаете ли вы, что если ничего не известно, и нет 100% гарантии, но ее нужно обеспечить для оставшейся части приложения, то пустой except end - это решение вопроса?
-
to Игорь Шевченко © (17.01.09 21:36) [160]: >Как это не может быть исправлена программистом - может быть исправлена >программистом. Например, вылавливанием этого AV, пардон, >протоколированием его, и продолжением разбора следующей части. Может мы немного разошлись в терминологии, но как мне кажется, это не исправление, а обработка ошибки. Данные, они как были кривыми, так ими и останутся.
-
vuk © (17.01.09 22:12) [164]
> Может мы немного разошлись в терминологии, но как мне кажется, > это не исправление, а обработка ошибки. Данные, они как > были кривыми, так ими и останутся.
Да, конечно, обработка. Об исправлении данных речь в большинстве случаев не ведется, хотя встречаются и такие ситуации, где ошибочные данные могут быть исправлены. Но эта ошибка (с логом) аналогична той, что некто ввел в цифровое поле вместо 11234 значение 112ЗЧ (на мой такой простой взгляд)
oxffff © (17.01.09 22:04) [163]
> Не считаете ли вы, что если ничего не известно, и нет 100% > гарантии, но ее нужно обеспечить для оставшейся части приложения, > то пустой except end - это решение вопроса?
Извини, это пустой разговор. Я могу еще раз привести в пример систему Windows - при ошибке в режиме пользователя она выдает сообщение об ошибке и продолжает работать, а при ошибке в режиме ядра валится с синим экраном. Sapienti Sat
-
> Игорь Шевченко © (17.01.09 21:46) [162] > oxffff © (17.01.09 21:44) [161]
> > Эта ошибка природу, которой установить невозможно > > > Не понял, поясни. Электричество кончилось - это внешняя > ошибка ? Альфа-частица пролетела сквозь планку памяти и > вызвала распад битов - это внешняя ошибка ?
Ваши примеры некорректны, такого рода исключения вполне известны. Будут сгенерированы соответствующие исключания процессора, которые Delphi замапит через const ExceptMap в sysutils. Я говорю о EExternalException.
Но тем не менее работать дальше надо, может все таки пустой try except?
> > что такое "общий словарь" ?
Это все типы исключений и кодов возвратов, которые известны вашему приложению(т.е. вам). Не EExternalException, и не исключения delphi опеределенные во внешнем DLL.
-
> Игорь Шевченко © (17.01.09 22:25) [165] > Извини, это пустой разговор. Я могу еще раз привести в пример > систему Windows - при ошибке в режиме пользователя она выдает > сообщение об ошибке и продолжает работать, а при ошибке > в режиме ядра валится с синим экраном. > Sapienti Sat
Это и есть разные зоны ответственности компонентов. Одни внешние имеют общую с режимом ядра зону ответственности.
Вторые - приложения пользователя раздельные зоны ответственности с режимом ядра. Система просто не пропускает их далее уже за сам механизм SEH.
Как пустой разговор?
Есть конкретно постановка задачи [137]. Есть решение с пустым except end там же.
Насколько я понимаю вы не находите в этом решении ничего плохого? Если да, то тему можно наконец то завершить.
-
Про пустой try...except И почти с плагинами Есть некоторое приложение. Висит слушает сокет а при подключении клиента поднимает COM объект реализующий этот интерфейс и позволяет клиенту его использовать. Конечно он ничего не знает о таких объектах - "плагинах". Я так полагаю, его разработчики тоже подумали - мало ли кто будет плагины писать - давай подстрахуемся будем исключения гасить. Как результат имеем ситуацию (реальная) массовые сигналы от пользователей - НЕ РАБОТАЕТ. Смотрим машину - загрузка процессора 20% свободной памяти несколько гигов, в логе никаких ошибок интерфейс самого приложения показывает состояние нормальной рабочей нагрузки. Только НИЧЕГО не работает и нет НИКАКИХ признаков что это не работает (кроме пользователей которых несколько тысяч и у которых от работоспособности системы зависят их доходы). Программист конечно молодец - его программа работает. Что делать тем кто ее эксплуатирует? Круглосуточно сидеть на телефоне? Кстати перезапуск программы решает проблему. На некоторое время.
-
oxffff © (17.01.09 23:13) [167]
> Есть конкретно постановка задачи [137]. > Есть решение с пустым except end там же.
Это неграмотное решение, потому что в случае возникновения ошибки информация о ней пропадает и о причине можно только гадать.
-
> Sapienti Sat
Да, да, спагетии мудрому понятны.
-
> oxffff (17.01.2009 21:30:39) [159]
Мне ничего, но я не участвую в обсуждение, просто пару сообщений, по некоторым моментам, бросаю и всего лишь. Но наверняка есть люди более заинтересованые в обсуждение люди. Поскольку меня перевоспитывать поздно, для себя я все решил, ну немного за других обидно и всего.
-
oxffff © (17.01.09 23:13) [167]
> Это и есть разные зоны ответственности компонентов. > Одни внешние имеют общую с режимом ядра зону ответственности. > > > Вторые - приложения пользователя раздельные зоны ответственности > с режимом ядра. Система просто не пропускает их далее уже > за сам механизм SEH.
Речь не идет о механизмах, речь идет о парадигме. Мало ли где какие механизмы - парадигма одна - об ошибках надо информировать тем или иным способом, соответственно об ошибках в данных - произвольным путем, по выбору, об ошибках в программе - лучше всего громким треском. Плагины и прочие внешние компоненты целесообразно рассматривать как данные.
-
> Игорь Шевченко © (17.01.09 23:23) [169] > oxffff © (17.01.09 23:13) [167] > > > > Есть конкретно постановка задачи [137]. > > Есть решение с пустым except end там же. > > > Это неграмотное решение, потому что в случае возникновения > ошибки информация о ней пропадает и о причине можно только > гадать.
Почему неграмотное? Где аргументы?
Если исключение при выполнении самого задания, оно будет отловлено и будет выслан в логгер информация, однако если ислючение возникнет исключение в логере оно будет проглочено, позволив обработать другие задания(приложения пользователя в вашем пример).
Теперь вопрос вам, как вы не зная реализации логера и его природу(DLL) можете обработать его ошибки? И привидите грамотное с вашей точки зрения решение, сохранив условие задачи.
for task in Tasks do begin try try task.execute; except ExternalLoger.Inform('Task Error'); end; except end; end; Если
-
> Игорь Шевченко © (17.01.09 23:23) [169] > Это неграмотное решение, потому что в случае возникновения > ошибки информация о ней пропадает и о причине можно только > гадать. >
Не всегда есть необходимость изучать причину ошибки. Например, когда эти причины известны заранее, устранение их невозможно по каким-либо причинам, не зависящим от разработчика. Предположим, мне необходимо зажигать светодиодик при выполнении одного из трех условий. Условия генерируются тремя "черными ящиками", глючными до безобразия, а доступа у меня к ним нет ну никакого. Информация какой из них сглючил мне неважна - неглючных "черных ящиков" нету, замена не поможет. Остается лишь махнуть на них рукой, и в случае возникновения очередной ошибки просто проигнорировать ее.
-
> Sergey Masloff (17.01.09 23:21) [168] >Игорь Шевченко © (17.01.09 23:26) [172]
Если ваше логирование встало(и вам известны причины поскольку известна реализация), у вас что есть второй журнал в который будет занесена информация о сбое логирования. А если он за сбоит? Есть Третий журнал?
Вопрос вы обертываете логирование в SEH или нет? Или позволяете рухнуть приложению при крахе логирования?
Я еще раз повторяю логирование внешнее. Нет никакого внутреннего логирования поскольку:
1. Логирование внешнее. 2. Отлавливаемые исключения неизвестны
Теперь я бы хотел получить более информативное разъяснение о неграмотном решении. А лучше с примером. Слова свои нужно подтверждать. :)
-
oxffff © (17.01.09 23:31) [173]
> Теперь вопрос вам, как вы не зная реализации логера и его > природу(DLL) можете обработать его ошибки? > И привидите грамотное с вашей точки зрения решение, сохранив > условие задачи.
Для меня недостаточно условий для приведения решения задачи, но в твоем коде я вижу два недостатка:
первый: если в методе task.execute возникнет исключение, то информация будет только о факте ошибки вообще. второй: если в методе task.execute возникнет исключение и в методе ExternalLogger.Inform возникнет исключение, то информации даже о факте ошибки не будет.
Кому нужна такая программа - я не в курсе.
-
KilkennyCat © (17.01.09 23:36) [174]
> Например, когда эти причины известны заранее, устранение > их невозможно по каким-либо причинам, не зависящим от разработчика. > Предположим, мне необходимо зажигать светодиодик при выполнении > одного из трех условий. Условия генерируются тремя "черными > ящиками", глючными до безобразия, а доступа у меня к ним > нет ну никакого. Информация какой из них сглючил мне неважна > - неглючных "черных ящиков" нету, замена не поможет. Остается > лишь махнуть на них рукой, и в случае возникновения очередной > ошибки просто проигнорировать ее.
На этот случай придуман оператор if :)
-
oxffff © (17.01.09 23:40) [175] Журнал один. Не удалось в него писать - рушимся.
Я описал ситуацию в которой из-за того что программист предпочел все втихую прятать возникают гигантские проблемы у пользователей. Если бы оно просто подыхало я поставил бы гуарда который хоть раз в 20 секунд проверял живо ли оно и если нет перезапускал бы. Хотя в данном случае и этого бы не нужно так как оно может работать как сервис я бы средствами винды поставил после ошибки перестарт и забыл бы.
-
> Игорь Шевченко © (17.01.09 23:26) [172] > oxffff © (17.01.09 23:13) [167] > Речь не идет о механизмах, речь идет о парадигме. Мало ли > где какие механизмы - парадигма одна - об ошибках надо информировать > тем или иным способом, соответственно об ошибках в данных > - произвольным путем, по выбору, об ошибках в программе > - лучше всего громким треском. > Плагины и прочие внешние компоненты целесообразно рассматривать > как данные.
Дык весь вопрос в том, что информацию пользователю попадает через логирование, которое в данном случае внешнее. Как быть если оно киркнулось, как сообшить пользователю о сбое. Можно попробовать так. Суть не меняется.
try try try task.execute; except ExternalLoger.Inform('Task Error'); end; except ExternalLoger.Inform('Logger crash); end; except end;
У вас нет возможности сообщить пользователю о сбое логера. Пользователь видет только свой лог.
-
> Игорь Шевченко © (17.01.09 23:44) [177]
Да, если я предполагаю, что такая ситуация будет вечно. В противном случае, я могу изначально написать "полуграмотно".
На мой взгляд, все-таки грамотность решения во многом определяется ТЗ и стоимостью. Грамотностью разработчика, конечно, тоже :)
-
oxffff © (17.01.09 23:48) [179]
> Дык весь вопрос в том, что информацию пользователю попадает > через логирование, которое в данном случае внешнее. Как > быть если оно киркнулось, как сообшить пользователю о сбое
Как сообщить пользователю о том, что компьютер, на котором выполнялась программа, перезагрузился из-за ошибки другого приложения ? Ответив на этот вопрос, ты получишь механизм оповещения о неисправном логгере
-
KilkennyCat © (17.01.09 23:50) [180]
> Да, если я предполагаю, что такая ситуация будет вечно
Я не совсем понял, какая ситуация имеется в виду ? Ситуация, что надо игнорировать ошибки о черных ящиков ?
Я о другом - народ настолько увлекся исключительными ситуациями, что забыл об их изначальном предназначении - информировать о том, что произошла ситуация, не предусмотренная алгоритмом. Поэтому считается, что можно втихую проигнорировать АБСОЛЮТНО ЛЮБУЮ ситуацию пустым блоком except end и продолжать, как ни в чем не бывало.
-
> Игорь Шевченко © (17.01.09 23:43) [176] > oxffff © (17.01.09 23:31) [173] > > > > Теперь вопрос вам, как вы не зная реализации логера и > его > > природу(DLL) можете обработать его ошибки? > > И привидите грамотное с вашей точки зрения решение, сохранив > > > условие задачи. > > > Для меня недостаточно условий для приведения решения задачи, > но в твоем коде я вижу два недостатка:
Не забываем добавлять IMHO.
> > первый: если в методе task.execute возникнет исключение, > то информация будет только о факте ошибки вообще.
Этого может вполне достаточно. Однако пример был упрощен. Можно расширить контракт, сохранив обобщенный подход. try try Task.Start; except try ErrorInfo:=Task.GetlastError; except ErrorInfo:='Task Unknown Error'; end; Log.Inform('ErrorInfo); end; except end
> второй: если в методе task.execute возникнет исключение > и в методе ExternalLogger.Inform возникнет исключение, то > информации даже о факте ошибки не будет.
Тут вы IMHO лукавите ? Если при исключении в вашем логере будет неустранимый сбой, как пользователь об этом узнает? Где здесь разница между внутренним и внешним логером?
Да и оборочиваете ли вы вызов логгера в try?
-
> Игорь Шевченко © (17.01.09 23:53) [181] > oxffff © (17.01.09 23:48) [179] > > > > Дык весь вопрос в том, что информацию пользователю попадает > > > через логирование, которое в данном случае внешнее. Как > > > быть если оно киркнулось, как сообшить пользователю о > сбое > > > Как сообщить пользователю о том, что компьютер, на котором > выполнялась программа, перезагрузился из-за ошибки другого > приложения ? Ответив на этот вопрос, ты получишь механизм > оповещения о неисправном логгере
Дык здесь и есть камень приткновения. Вы утверждаете что решение неграмотное. Неграмотность как я понимаю с вашего IMHO состоит в том, не обрабатывается ситуация сбоя логера. Дык, если внутренний известный логгер вам сбойнул, у вас есть возможность обработать его исключения, коды, ошибок. И возможно даже его восстановить. Если его восстановить нельзя (либо проглотить ошибку, либо с треском). Но тогда данная ситуация ничем не отличается о обобщенного решения. И я могу также сказать, что подобное ваше решение на внутреннем логере кривое, поскольку пользователь не узнает о сбое. Не так ли?
Честно говоря я надеюсь что вы аргументируете свое высказывание "кривое", поскольку другие участиники сделать этого не смогли.
Но!!! Сохранив условия задачи о неизвестном логере, сделать вы это не сможете. Поскольку сами подтвердили в [181].
Я без всяких обид приму Ваше, что с "кривым" я погорячился. Лично у меня вызывают глубокую симпатию грамотные люди, которые способды аргументировать свое точку зрения аргументами, а не общими фразами. Вы именно такой собеседник.
P.S. Повторю свою позицию для тех кто не видел
Ошибки для меня существуют. И поверь, что я не отстаиваю точку зрения что except end должен быть пустым всегда. Более того я и пишу, как все мои оппоненты, либо информативные коды возвратов, либо дерево классов исключений с проверкой в except end.
Я отстаиваю точку зрения, что может быть и except end пустым (а это между прочим тема начальной беседы) и привел контректный пример.
-
oxffff © (17.01.09 23:59) [183]
> Не забываем добавлять IMHO.
Нет, без всякого IMHO - это вполне объективные недостатки, либо, как я уже говорил, исходных данных для построения алгоритма недостаточно.
Я в данном случае согласен с Сергеем Масловым - не удалось записать в журнал, надо вылетать с треском и информировать пользователя тем же самым способом, что и при перезапуске компьютера из-за ошибки другого приложения.
-
to Игорь Шевченко © (18.01.09 00:26) [185]: >Я в данном случае согласен с Сергеем Масловым - не удалось записать в >журнал, надо вылетать с треском и информировать пользователя тем же >самым способом, что и при перезапуске компьютера из-за ошибки другого >приложения. Я бы попробовал вместо вылета для начала в системный журнал начать писать, он достаточно надежен. И вот если и этим тоже облом, то тогда уже точно хана.
-
> Игорь Шевченко © (18.01.09 00:26) [185] > oxffff © (17.01.09 23:59) [183] > > > > Не забываем добавлять IMHO. > > > Нет, без всякого IMHO - это вполне объективные недостатки, > либо, как я уже говорил, исходных данных для построения > алгоритма недостаточно.
Подождите вы сказали, именно о неграмотном решении. Значит вы знаете как грамотно разрешить ситуацию, которая в моей реализации упрощенного обобщенного способа не разрешается. Тогда я жду, как вы разрешите ситуацию с информированием пользователя через логер информацию о сбое самого логера.
Есть принципиальная разница.
Между вашими словами, что я привел неграмотное решение(т.е фактически указав, что я не профессионал, но пока не аргументировав контрпримером), и тем, что не существует способа решить эту задача при данных условиях(конкретно неизвестный логер), наделив пользователя 100% гарантией уведомления о всех ошибках, есть огромная разница. Т.е. по факту вы здесь не правы.
Либо признайте, что погорячились, либо привидите пример.
А то знаете ли хорошего человека просто так обозвали. > > Я в данном случае согласен с Сергеем Масловым - не удалось > записать в журнал, надо вылетать с треском и информировать > пользователя тем же самым способом, что и при перезапуске > компьютера из-за ошибки другого приложения.
А почему должны страдать другие задачи? Если есть возможность их исполнять. Или вы всех неустранимых ошибках логера, который выполняет для большинства задач второстепенную работу(естественно это не СУБД), рушите все приложение.
-
vuk © (18.01.09 00:37) [186]
> Я бы попробовал вместо вылета для начала в системный журнал > начать писать, он достаточно надежен. И вот если и этим > тоже облом, то тогда уже точно хана.
Собственно, мы так и делаем
oxffff © (18.01.09 00:41) [187]
"Для меня недостаточно условий для приведения решения задачи, но в твоем коде я вижу два недостатка:" (с) пост [176] Далее эти недостатки подробно разобраны по приведенному примеру кода.
-
> Игорь Шевченко © (18.01.09 00:59) [188] > oxffff © (18.01.09 00:41) [187] > > "Для меня недостаточно условий для приведения решения задачи, > но в твоем коде я вижу два недостатка:" (с) пост [176] > Далее эти недостатки подробно разобраны по приведенному > примеру кода.
Я честно говоря ожидал, что вы мудрее по жизни. А вы до последнего не хотите признавать, что погорячились. Вы же прекрасно понимаете, то что вы указали в [176] является постановкой и следствием задачи и никак не связно с моим решением. Мне жаль, что вы как человек не можете этого признать. :(
-
oxffff © (18.01.09 01:05) [189]
> Я честно говоря ожидал, что вы мудрее по жизни.
Я сожалею, что обманул твои ожидания. На этой ноте, я полагаю, дискуссию можно завершить
-
> Игорь Шевченко © (18.01.09 01:13) [190]
Игорь, как раз в [190] ты и проявил мудрость по жизни. :о)
-
> Игорь Шевченко © (18.01.09 01:13) [190] > oxffff © (18.01.09 01:05) [189] > > > > Я честно говоря ожидал, что вы мудрее по жизни. > > > Я сожалею, что обманул твои ожидания. На этой ноте, я полагаю, > дискуссию можно завершить
Теперь, тогда нет. Я буду добиваться от вас грамотного решения.
Итак к делу.
Есть
ITask=interface procedure execute; end;
ILogger=interface procedure inform(const Message:string); end;
Постановка задачи:
Есть набор заданий. Задание из себя представляет контракт ITask. Есть логгер внешний Логгер из себя представляет контракт ILogger.
Необходимо произвести запуск всех заданий, в случае возникновения исключения при выполнении задания, информировать о провале задания через логгер. Методы логгера также генерируют исключения в случае провала. Необходимо обеспечить пункты из [176]. Все исключения генерируемые ITask,ILogger - есть экземпляры EExtrernalException.
-
> Юрий Зотов © (18.01.09 01:28) [191] > > Игорь Шевченко © (18.01.09 01:13) [190] > > Игорь, как раз в [190] ты и проявил мудрость по жизни. > :о)
Да и вы туда же, смотрю задел я вас тогда замечанием о вашей реализацией синглетона. Шайка прям. Все за друг друга. Вась. Вась. Все отличились и А.П. тоже как получил от меня замечание. Но тоже не признал.
Может тогда решите совместно грамотно [192].
-
> oxffff © (18.01.09 01:28) [192]
Обязательным требованием является то, что пользователь может выдеть только тот результат, который отослан ему через ILogger. Искомое приложение запускается за отдельно стоящей машине, без GUI. Любое логирование или информирование должно происходить только через ILogger.
-
> oxffff © (18.01.09 01:32) [193]
Нет, я тоже проявлю мудрость по жизни. Существует категория людей, спорить с которыми не нужно.
LOL
-
> > oxffff © > > Игорь Шевченко © > Теперь, тогда нет. > Я буду добиваться от вас грамотного решения.
Я думаю теперь в противном случае вы либо приводите грамотное решение с учетом [176],[192],[194]. Либо признаете, что погорячились, либо подтвердите свои слова грамотным решением.
-
> Юрий Зотов © (18.01.09 01:42) [195]
Никто не говорит о споре с кем либо. Пожалуйста есть утвреждение, которое нужно подтвердить, либо отказаться. Либо номер № 3, сделать как вы. :) Ну что я могу сделать, это ваш выбор.
Я давном случае, я хочу отстоять свое право оставаться профессионалом(и возможно сложившийся авторитет для кого-то. А это знаете ли немало.) Не больше и не меньше. Вас уличить у меня цели нет.
-
> Юрий Зотов © (18.01.09 01:42) [195] > > oxffff © (18.01.09 01:32) [193] > > Нет, я тоже проявлю мудрость по жизни. Существует категория > людей, спорить с которыми не нужно.
Но тем не менее в своей статье упомянули возможность изменить ваше решение чуть его сократив, тихо умолчав кто его вам дал. :) Эх, Юрий, Юрий.
-
> oxffff © (18.01.09 01:58) [198]
Юрий Зотов © Помните про
if _Singleton = nil then //Можно и без проверки
-
> Существует категория людей, спорить с которыми не нужно.
Вот это точно. Бо они заточены именно на споры. Суть спора их не очень волнует.
-
> [137] oxffff © (17.01.09 20:33)
подобные ошибки должны логироваться централизованно, а не на местах, с пом. спец. средств, например JCL. все исключения, кроме ряда специализированных (например в Indy некоторые исключения сигнализируют далеко не об ошибке) нужно логировать. не обработанные исключения тоже нужно логировать, но при этом сообщая через UI о том, что произошла ошибка.
-
Удалено модератором
-
> Eraser © (18.01.09 02:41) [201] > > [137] oxffff © (17.01.09 20:33) > > подобные ошибки должны логироваться централизованно, а не > на местах, с пом. спец. средств, например JCL. все исключения, > кроме ряда специализированных (например в Indy некоторые > исключения сигнализируют далеко не об ошибке) нужно логировать. > не обработанные исключения тоже нужно логировать, но при > этом сообщая через UI о том, что произошла ошибка.
Это generic алгоритм, который испоняется на отдельной тачке без GUI с возможным падением логгера и единственной возможностью сообщить только через него. Такова поставновка задачи. С ограниченной фукнциональностью контрактов. Такова поставновка задачи. Естественно я приводил данный упрощенный код для выявления потребности в пустом except end. А в итоге мы уже далеко отошли от этого. Оппонент по факту признался в невозможности решения в [181]. Однако официально не признает этого. Мог бы получить союзника, а так получат опонента пожизненно.
-
> Это generic алгоритм, который испоняется на отдельной тачке > без GUI с возможным падением логгера и единственной возможностью > сообщить только через него. Такова поставновка задачи.
так ответили же уже - записывать в системный журнал. если и при этом ошибка, можно записывать в самопальный лог, ввиде текстового файла. если и там ошибка - генерировать не обрабатываемое исключение, либо закрывать поиложение с определенным кодом ошибки.
-
procedure DoTask(const Task:ITask;const Log:ILog); begin try Log.Inform('Task Start'); Task.Start; Log.Inform('Task End'); except try Task.TryToCloseTask; except try Log.Inform('Task close Error'); except on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); end; end; try Log.Inform('Task Error'); except on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); end; end; end;
-
on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); Можно менять на что угодно, но информация о том что произошла ошибка должна быть, хочеш тут завершай приклад, хочеш пиши самопальный лог. Да еще вопросик а почему ты информацию о задании в лог не пишешь? Как потом из всего множества заданий искать тот в котором произошла ошибка?
-
>Eraser © (18.01.09 03:15) [204] > test (18.01.09 06:38) [205]
Почему мы опять игнорируем пункт задания. Все сообщения пользователя идут только ILOG(в задании сказано логирование у yнас только внешнее). У нас нет никаких внутренних журналов. Это принципильный вопрос ребята.
Теперь конкретно по реалиазции не связанныго с моим заданием test (18.01.09 06:38) [205]
try Log.Inform('Task Start'); Task.Start; Log.Inform('Task End');
except try Task.TryToCloseTask; except try Log.Inform('Task close Error'); except on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); end; end;
try Log.Inform('Task Error'); except on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); end; end;
Любое исключение в Log.Inform('Task Start')| Task.Start;| Log.Inform('Task приведет к Task.TryToCloseTask, Log.Inform('Task Error'). Что некорректно. + как следствие дизинфоромация пользователя.
Теперь по оформлению, если не классификации исключений (обрабатываюстя все исключения) достаточно вместо on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); написать MessageDlg(ExceptObject.message,mtError,[mbOK],0);
Теперь главный вопрос почему сделано предположение о том, что сам MessageDlg(e.message,mtError,[mbOK],0); не вызовет исключение? Ведь 100% уверенности что в том, что это он не сделает нет. Тем более на машине на которой никто не сидит и не видит этих сообщений. (Рано или поздно кончатся ресурсы) Это не параноидальный подход. Это когда нужно гарантировать выполнение следующих заданий, опять же по условию задачи.
-
> Да еще вопросик а почему ты информацию о задании в лог не > пишешь? > Как потом из всего множества заданий искать тот в котором > произошла ошибка?
Ответ простой. Получить это информацию о задании нет возможности, есть только возожность ее выполнить. Таков контракт по заданию.
Во первых все информацию о работе (в том числе и о ислючениях)паралельно может писать Task внутри свой внешней реализации, которая нам не доступна. Почему то никто до этого не смог догадаться. Но может также и не писать. Это вопрос реалиазции Task.
-
> on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); > > написать > MessageDlg(ExceptObject.message,mtError,[mbOK],0);
Здесь звиняй, не прав я. ExceptObject тип Tobject.
-
> oxffff © (18.01.09 11:25) [209]
Однако писать для обработки всех исключений on e:Exception do MessageDlg(e.message,mtError,[mbOK],0); некорректно. Поскольку никто не запрещает нам например сделать raise Tform1.create(nil);
-
to oxffff © (18.01.09 11:19) [207]: >Все сообщения пользователя идут только ILOG(в задании сказано >логирование у yнас только внешнее). У нас нет никаких внутренних >журналов. >Это принципильный вопрос ребята. Я уже здесь писал, что догматизм вреден. В том числе в той форме, когда в ущерб возможности понимания того, что есть проблемы (о которых можно сообщить в системном журнале) начинается бессмысленное упирание в крувую постановку задачи.
-
Удалено модератором Примечание: Предупреждаю: еще один переход на личности - будешь забанен. Надоело твою грязь чистить.
-
> oxffff (17.01.2009 23:59:03) [183]> except > ErrorInfo:='Task Unknown Error'; > end; Я уже тебе приводил правильный код, не надо прятать реальную ошибку. Пользователь будет очень рад подобному жизнерадостному сообщению.
except
on E:Exception do
ErrorInfo:= 'Task Unknown Error: ' + E.Message;
end;
-
> oxffff (18.01.2009 13:43:32) [212]
Зачем приписываешь свои мысли другим. Ты уже начал кидаться на участников, оскорблять их. Чувствую ветка доживает свои последнии часы.
-
> Anatoly Podgoretsky © (18.01.09 13:44) [213]
Неправильно. А как насчет raise Tform.create(nil), не с корнем в Exception?
> Я уже тебе приводил правильный код, не надо прятать реальную > ошибку. Пользователь будет очень рад подобному жизнерадостному > сообщению. > > except > on E:Exception do > ErrorInfo:= 'Task Unknown Error: ' + E.Message; > end;
Для уже написал, что исключение внешение. У вас будет только Message='External Exception'.
Опять додумываете. Куда вы бутите слать его логер дает исключение? cм. [212] внимательно пожалуйста на слова обобщенный алгоритм, спасибо.
-
> oxffff © (18.01.09 13:43) [212] > Учитесь думать обобщенно. А я вам в этом помогу.
не надо :)))
вот смотри: у тебя есть некий плагин, который может свалиться даже на записи своих ошибок, житейская вещь. если это происходит, в самом фиговом случае мы видим чистый лог и полное отсутствие результатов работы плагина. Админ будет чесать репу очень долго и поминать тебя плохими словами. Чтобы этого не было, неплохо завести лог ошибок логгирования, в реализации простой, как три копейки. Плагины - не твое твое творчество, с т.з. системы им доверять нельзя, в них может происходить что угодно по опеределнию. Но и при его работе могут возникнуть исключения (диск переполнился). Можно, конечно, завести еще один уровень, который будет писать в журнал, над ним еще, который будет писать письмо путину и т.д. Не здОрово. можно гасить исключения, приходим к тому, от чего ушли, но с меньшими вероятностями. Выход можно содрать у оракловых утилит: в настройках указаывается, на какой по счету ошибке обработки им с треском сваливаться. Т.е. в нашем случае если, например, плагин 100 раз вызвал ошибку и не смог ее записать в лог, и мы в своем логе не можем ее отразить, потому что диск вылетел, этот плагин явно надо срубать, ничего хорошего от него не выйдет сегодня. А число 100 пусть подбирает админ.
-
> oxffff © (18.01.09 13:43) [212] > Удалено модератором > Примечание: Предупреждаю: еще один переход на личности - > будешь забанен. Надоело твою грязь чистить.
Хорошо я напишу, корректней.
Есть обобщенней алгоритм:
Есть неизвестное задание А, и неизвестный логер B. Согласно обобщенного алгоритма при возникновенеии исключение в А, должно быть сообщено в B. Однако исключение в B не должно рушить приложение. А и B генерируют неизвестные, внешние исключения, т.е. это будет экземпляр EExternalException.
Любое сообщение пользователю должно идти через B(ILogger), таким образом предложения писать в системный лог идут в разрез в самой идеей генерализации. Фактически в таком случае нужно вообще отказаться от идеи генерализации логирования.
-
> > Petr V. Abramov © (18.01.09 14:04) [216]
Славо богу хоть ты успел прочитать.
-
> Petr V. Abramov © (18.01.09 14:04) [216] > > > oxffff © (18.01.09 13:43) [212] > > Учитесь думать обобщенно. А я вам в этом помогу. > > не надо :))) > > вот смотри: у тебя есть некий плагин, который может свалиться > даже на записи своих ошибок, житейская вещь. если это происходит, > в самом фиговом случае мы видим чистый лог и полное отсутствие > результатов работы плагина. Админ будет чесать репу очень > долго и поминать тебя плохими словами. > Чтобы этого не было, неплохо завести лог ошибок логгирования, > в реализации простой, как три копейки. Плагины - не твое > твое творчество, с т.з. системы им доверять нельзя, в них > может происходить что угодно по опеределнию. Но и при его > работе могут возникнуть исключения (диск переполнился). > Можно, конечно, завести еще один уровень, который будет > писать в журнал, над ним еще, который будет писать письмо > путину и т.д. Не здОрово.
Плагины это как пример использования идеи генерализации. Я намеренно упросил задачу, для выявления пустого except end
Можно например представаить код который выполняется в дополнительном потоке, с его логированием. Можно например представаить работа с СУБД в дополнительном потоке, с его логированием. Возможности получить описания исключения нет(упрощено, можно делегировать этот контракт ITask в качестве решения, но не в этом суть). Важно!!! Что любое логирование идет через обобщенный контракт.
Вот здесь [216] ты намеренно пытаешься уйди о идеи генерализации. Ты предлагаешь завязаться на конкретном варианте логирования(фактически расширив его и специализировав). То есть хорошо давай предположим, что есть то я бы предложил в твоей версии
Есть генерализация
(IAbstractTask, IAbstractLogger, IAbstractLoggerOfLoggeerErrors).
Ты предлагаешь сузить генерализацию до
(ITask, ILogger, ConcreteWin32SystemEvent).
фактически ограничив ее, что противоречит условию задачи. Алгоритм должен быть обобщен. Однако и в том и в другом случае нет возможности гарантировать не защитив Logger, что за него уйдет исключение. Я надеюсь ты меня понял.
-
Удалено модератором Примечание: Вас предупреждали ? Предупреждали. Отдыхайте
-
> Есть генерализация > > (IAbstractTask, IAbstractLogger, IAbstractLoggerOfLoggeerErrors). >
> > Ты предлагаешь сузить генерализацию до > > (ITask, ILogger, ConcreteWin32SystemEvent). > > фактически ограничив ее, что противоречит условию задачи. > > Алгоритм должен быть обобщен.
ну тогда пустой try..except админам в темном переулке будешь про обобщенные алгоритмы расказывать
|