Форум: "Прочее";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];
ВнизExceptions considered harmful ? Найти похожие ветки
← →
isasa © (2008-01-26 12:48) [80]ЗЫ. Я хотел сказать, что в рамках проекта желательно иметь однообразие. Но не более. Вот и все.
← →
Kolan © (2008-01-26 13:05) [81]> У тебя есть механизм. Что с ним делать, решается в данном
> конкретном случае, руководствуясь принятыми правилами для
> данного случая, местности, времени …
То есть
«Всякий овощ приносит пользу, будучи употреблен надлежащим образом в надлежащее время :)» © Игорь Шевченко
:)
← →
Sandman25 (2008-01-26 13:24) [82]isasa © (26.01.08 12:47) [79]
В Java генерируемые исключения описываются в сигнатуре метода. Если хочешь, чтобы кто-то что-то обрабатывал, так и пишешь в сигнатуре. И без обработки соответствующего исключения никто ничего даже не вызовет. а не как в Delphi: вызвал, код забыл проанализировать и пошел использовать неверные данные. Может, поэтому access violation в Java нету? :)
← →
Kolan © (2008-01-26 13:34) [83]> 4. Очень помогает вложенность Exception, то есть я могу
> получить от сервера один Exception, внутри которого находится
> другой, внутри него третий и т.д. Например, невозможно получить
> данные, потому что не найден объект, потому что произошла
> ошибка БД, потому что неверно указано наименование таблицы.
А как это? Я незнал. Где прочесть?
← →
Sandman25 (2008-01-26 13:58) [84]Kolan © (26.01.08 13:34) [83]
Если речь про Delphi, то нужно самому реализовывать: добавить класс TNestingException, у которого будет поле nestedException: TNestingException, а уже от этого класса наследоваться
← →
Игорь Шевченко © (2008-01-26 14:04) [85]Sandman25 (26.01.08 13:58) [84]
Не совсем понял, зачем такое ? Вот например есть Exception EDBEngineError, внутре которого находится вполне себе подробная информация о том, какая именно задница стряслась. Я к тому, что никто не мешает создать наследник класса Exception с необходимыми подробностями.
Или я чего-то не понял ?
← →
Kolan © (2008-01-26 14:10) [86]> то нужно самому реализовывать
А, я подумал есть стандартное что-то, хелп читать стал.
← →
guav © (2008-01-26 14:19) [87]Ветка не совсем бестолковая. Я убедился, что мнения сильно отличаются, и есть согласные с тем, что при potential logic or user input errors, such as the overflow of an array boundary не следует кидать исключения. Поэтому решил последовать рекомендациям не использовать исклюение для необычной, но ожидаемой ситуации.
← →
Sandman25 (2008-01-26 14:20) [88]Игорь Шевченко © (26.01.08 14:04) [85]
Композиция позволяет решить "проблему" отсутствия множетсвенного наследования. Например, причиной отказа распределенной транзакции может быть ошибка сервера приложений, ошибка авторизации, ошибка БД и т.д. Эти классы не наследуются один от другого, поэтому и нельзя использовать наследников.
← →
guav © (2008-01-26 14:28) [89]> [85] Игорь Шевченко © (26.01.08 14:04)
> Или я чего-то не понял ?
Видимо, речь идёт о Java подходе, где если TStream.Read может бросать только EReadError, то наследник TStream, читающий из БД, может кинуть только EReadError, но в этот EReadError может быть вложен и EDBEngineError.
← →
Kolan © (2008-01-26 14:34) [90]> Поэтому решил последовать рекомендациям не использовать
> исклюение для необычной, но ожидаемой ситуации.
Хорошо, есть свойствоFileName
и операцияDoSmth
.procedure DoSmth;
begin
if FileExists(FFileName) then
…
else
raise ERequiredFileNotFoundException.Create();
end;
Как поступишь?
А. Если пишешь програму.
Б. Если пишешь компонент.
← →
Sandman25 (2008-01-26 14:39) [91]Kolan © (26.01.08 14:34) [90]
Надо усложнить задание.
Не процедура, а метод, возвращающий, скажем массив объектов, которые были считаны из файла.
← →
Игорь Шевченко © (2008-01-26 14:39) [92]Sandman25 (26.01.08 14:20) [88]
Не совсем понимаю, причем тут множественное наследование. Или перечисленные тобой ситуации должны представлять именно отдельные классы, а не, скажем, значение поля reason в классе EDistrinuteTransactionException ?
← →
Игорь Шевченко © (2008-01-26 14:41) [93]Kolan © (26.01.08 14:34) [90]
Я не советую писать такой компонент. Это неверно в общем случае.
← →
Sandman25 (2008-01-26 14:50) [94]Игорь Шевченко © (26.01.08 14:39) [92]
Как потом по этому reason узнать, что явилось причиной причины?
А множественное наследование при том, что если наследовать EDistrinuteTransactionException от EDBEngineError, то непонятно, что делать в случае ESocketError
← →
Kolan © (2008-01-26 14:53) [95]> Я не советую писать такой компонент. Это неверно в общем
> случае.
А программу?
← →
guav © (2008-01-26 14:56) [96]> [90] Kolan © (26.01.08 14:34)
> if FileExists(FFileName) then
Ну так я не делаю. В if файл может существовать, в then уже нет, это пример race condition в многозадачной среде. Можно, конечно, считать что такое редко бывает, но не в моём случае.
Если файл надо открыть, то сразу его и открыват.
Т.е.
выбор между
TFileStream.Create(FFileName, ...)
и
Handle := CreateFile(FFileName, ...)
if Handle = INVAID_HANDLE_VALUE
TFileStream.Create(Handle)
Пишу программу.
← →
Kolan © (2008-01-26 15:04) [97]> 96] guav © (26.01.08 14:56)
Ладно, не спорю, а где код ошибки или как ты о ошибке уведомляешь(о чем собссно и ветка)?
← →
Игорь Шевченко © (2008-01-26 15:27) [98]Sandman25 (26.01.08 14:50) [94]
> Как потом по этому reason узнать, что явилось причиной причины?
Это как ?
Причина - возбуждение исключения EDistributedTransactionException, причина его возбуждения - значение поля Reason.
Какие еще причины причин нужны ?
← →
Sandman25 (2008-01-26 15:33) [99]Игорь Шевченко © (26.01.08 15:27) [98]
То есть Вы ограничиваетесь 1 уровнем вложенности. А если я захочу узнать, в чем причина причины?
EDistributedTransactionException имел причиной EAuthorizationError, а тот имел причиной EDBEngineError. Грубо говоря - при попытке проведения транзакции не удалось проверить доступ, потому что не удалось подключиться к БД.
Парадигма простая - у любого Exception может быть причина. А может и не быть :)
← →
Игорь Шевченко © (2008-01-26 15:47) [100]Sandman25 (26.01.08 15:33) [99]
> А если я захочу узнать, в чем причина причины?
А какой в этом смысл ? Нарушается принцип объектно-ориентированного программирования: от устройства объекта не должно зависеть поведение более высоких уровней. В твоем случае у класса EDistributedTransactionException должен быть метод get_Reason, который уже сам обрабатывает всю внутреннюю кухню, но в интерфейсе этого класса тебе доступен только этот метод.
← →
Sandman25 (2008-01-26 15:55) [101]Игорь Шевченко © (26.01.08 15:47) [100]
А я и не призываю это правило нарушать.
Есть контракт, его нельзя изменять. Не должны бросаться исключения, специфичные для реализации класса. Грубо говоря, клиенту не должны бросаться EDBEngineError , потому что завтра мы начнем хранить данные в файлах и у нас вместо EDBEngineError будут бросаться EFileNotFoundError. Этого можно добиться, заворачивая низкоуровневые исключения в высокоуровневые. То есть и клиента не надо переписывать, и никакая специфическая информация не потеряна.
← →
Игорь Шевченко © (2008-01-26 16:05) [102]Sandman25 (26.01.08 15:55) [101]
Не знаю, как в Java, но в Delphi вполне себе возможно выстроить иерархию классов исключений :) При этом клиент и не узнает, что на самом деле он обрабатывает исключение EStupidUserError, а будет обрабатывать Exception и пользоваться его методами. И знать о том, что именно EStupidUserError он может обрабатывать, ему вовсе необязательно. Все в рамках контракта.
← →
Sandman25 (2008-01-26 16:11) [103]Игорь Шевченко © (26.01.08 16:05) [102]
В Java тоже никто не мешает объявить в контракте throws Exception и работать как в Delphi :) Но это редко будет хорошей идеей.
← →
guav © (2008-01-26 17:17) [104]> [97] Kolan © (26.01.08 15:04)
> а где код ошибки или как ты о ошибке уведомляешь(о чем собссно
> и ветка)?
в случае, когда без исключения - он в GetLastError(), если он действительно интересует и от него зависит обработка, он может быть обработан в case, при этом для неожиданных кодов можно и кинуть исключение. В случае с исключением он в самом исключении.
Кстати, почему мне не нравится кидать исключения из GetLastError() кодов:
Допустим мы действительно хотим программно обработать некоторые коды, алгоритм предусматривает это.
Например, при ERROR_MORE_DATA мы удваиваем буфер и повторяем попытку, ну и допустим при ERROR_NO_ACCESS мы пытаемся получить этот самый Access.
вот код без исключений
IoCallSucceeded := DeviceIoControl(... );
if not IoCallSucceeded then
case GetLaseError() of
ERROR_MORE_DATA:
begin
...
end;
ERROR_NO_ACCESS:
begin
...
end;
else
RaiseLastOSError();
end;
end;
с исключениями вроде бы логично ему выглядеть так:
try
Win32Check(DeviceIoControl(... ));
except
on EMoreData do
begin
...
end;
on EAccessDenied do
begin
...
end;
end;
но на самом деле коды ошибки всё равно предстоит обработать:
try
Win32Check(DeviceIoControl(... ));
except
on E: EOSError do
case E.ErrorCode of
ERROR_MORE_DATA:
begin
...
end;
ERROR_NO_ACCESS:
begin
...
end;
else
raise;
end;
end;
причём, несмотря на то что исключение может быть свачено уровнем выше, осмысленная обработка возможна только на этом уровне. т.е. исключения, сделаные из кодов ошибки, легче донести до пользователя/до крэш репорта, но когда их надо именно обработать, они хуже самих кодов.
← →
ketmar © (2008-01-26 21:16) [105]>[75] isasa ©(26.01.08 11:04)
а ты и вовсе не о том говоришь.
а за ловлю всех исключений надо кастрировать тупой пилой.
>[82] Sandman25 (26.01.08 13:24)
нет. AV там нет потому, что нет указателей. а вот падение жабового софта с воплем «unhandled exception» — ситуация вполне частонаблюдаемая.
← →
Игорь Шевченко © (2008-01-26 21:35) [106]guav © (26.01.08 17:17) [104]
> с исключениями вроде бы логично ему выглядеть так:
> try
> Win32Check(DeviceIoControl(... ));
> except
> on EMoreData do
> begin
> ...
> end;
> on EAccessDenied do
> begin
> ...
> end;
> end;
Избавь Аллаха от работы с таким кодом. Именно что-то подобное я и имел в виду, когда говорил, что код, где логика построена на исключениях непонятен, несопровождаем и крайне неудобен в отладке.
← →
Kolan © (2008-01-26 21:39) [107]> Именно что-то подобное я и имел в виду
Такой еод и мне ненравится…
← →
Игорь Шевченко © (2008-01-26 21:41) [108]Kolan © (26.01.08 21:39) [107]
> Такой еод и мне ненравится…
Чем и почему ?
← →
Kolan © (2008-01-26 21:54) [109]> Чем и почему ?
Нечитается. Однако в коде с оброботкой кодов, эксепшен все равно есть…
← →
Черный Шаман (2008-01-26 22:27) [110]
> ketmar © (26.01.08 21:16) [105]
>
> >[75] isasa ©(26.01.08 11:04)
> а ты и вовсе не о том говоришь.
> а за ловлю всех исключений надо кастрировать тупой пилой.
Если ты пишеш программу, то стоит ловить все исключения на верхнем уровне и логировать.
← →
ketmar © (2008-01-26 23:25) [111]>[110] Черный Шаман (26.01.08 22:27)
если я пишу программу, то обычно до «верхнего уровня» никто не доползает, ибо ловится там, где полагается. а если что-то доползло — делается post mortem дамп и всё схлопывается. ибо это fatal error.
← →
Черный Шаман (2008-01-27 17:46) [112]
> ketmar © (26.01.08 23:25) [111]
>
> >[110] Черный Шаман (26.01.08 22:27)
> если я пишу программу, то обычно до «верхнего уровня» никто
> не доползает, ибо ловится там, где полагается. а если что-
> то доползло — делается post mortem дамп и всё схлопывается.
> ибо это fatal error.
Если бы все так писали, то до сих пор сидели бы на DOS 10.х, но зато вылизанном и стабильном.
PS
Узнайте как часто в устройствах используется watch dog - при зависании устройства(отсутствии обращения к устройству х секунд) микросхема просто перегружает устройство.
PS2
Представим что вы пищете программу для ядерной энергетики, но тут ваш напарник в коде прописал исключение
if time then raise Exception.create("Пасхальное яйцо");
Программа упала при вытянутых стержнях - реактор рванул, вместо того чтобы залогировать ошибку и продолжить работу, пусть хоть и в аварийном режиме.
← →
Loginov Dmitry © (2008-01-27 18:17) [113]> Представим что вы пищете программу для ядерной энергетики,
> но тут ваш напарник в коде прописал исключение
> if time then raise Exception.create("Пасхальное яйцо");
> Программа упала при вытянутых стержнях - реактор рванул,
> вместо того чтобы залогировать ошибку и продолжить работу,
> пусть хоть и в аварийном режиме.
А если напарник сделаетif time then TerminateProcess(DWORD(-1), 0)
тоже будешь пытаться залоггировать? ))
← →
DiamondShark © (2008-01-27 21:32) [114]
> вот код без исключений
>
> IoCallSucceeded := DeviceIoControl(... );
> if not IoCallSucceeded then
> case GetLaseError() of
> ERROR_MORE_DATA:
> begin
> ...
> end;
> ERROR_NO_ACCESS:
> begin
> ...
> end;
> else
> RaiseLastOSError();
> end;
> end;
Который катастрофически некорректный.
← →
ketmar © (2008-01-27 22:41) [115]>[112] Черный Шаман (27.01.08 17:46)
>Если бы все так писали
мне плевать, как пишут «все». многие «все» восхищаются сишарпом и вротнетом, например. я, что ли, этих недоучек наплодил?
>Узнайте как часто в устройствах используется watch dog
узнай, что мой подход никак не отменяет возможности использовать watchdog — в отличие от твоего. при этом у меня есть вся информация, чтобы разобраться, отчего оно рухнуло, а у тебя — куцый лог, по которому можно отпределить только среднюю температуру по больнице.
>Представим что вы пищете программу для ядерной энергетики
представь, что софт подобного уровня на Delphi не пишут — слишком сложный язык.
к тому же твой пример — идиотский.
← →
guav © (2008-01-28 09:30) [116]> [114] DiamondShark © (27.01.08 21:32)
> Который катастрофически некорректный.
Где ошибка ?
← →
DiamondShark © (2008-01-28 11:41) [117]
> guav © (28.01.08 09:30) [116]
> > [114] DiamondShark © (27.01.08 21:32)
> > Который катастрофически некорректный.
>
> Где ошибка ?
В ДНК.
Каков результат RaiseLastOSError после вызова GetLastError?
← →
DiamondShark © (2008-01-28 11:41) [118]
> guav © (28.01.08 09:30) [116]
> > [114] DiamondShark © (27.01.08 21:32)
> > Который катастрофически некорректный.
>
> Где ошибка ?
В ДНК.
Каков результат RaiseLastOSError после вызова GetLastError?
← →
ketmar © (2008-01-28 12:01) [119]>[117] DiamondShark ©(28.01.08 11:41)
нормальный. GetLastError() не сбрасывает переменную с кодом ошибки.
← →
guav © (2008-01-28 12:45) [120]> [117] DiamondShark © (28.01.08 11:41)
Не вижу проблемы, даже в некоторых примерах MSDN GetLastError() опрашиваентся несколько раз.
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];
Память: 0.69 MB
Время: 0.043 c