GlebZ wrote: > Здравствуйте, IT, Вы писали: > > IT>А разве это не так? Что тогда подразумевается под "документ не всегда может быть "хорошо сгенерирован" (например, слишком большая картинка,"? Я это понял как не может быть сгенерирован. > Одно из моих личных IMHO. > Производители компиляторов (по крайней мере С++ и JIT) так старались чтобы исключительные ситуации были исключительными по самые уши. То бишь обработки их более чем тормозные. Поэтому, если можно обработать (а практически всегда можно) ошибки логикой и не доводить до исключения, то их нужно обрабатывать логикой. Исключения нужны только для отладки. > > С уважением, Gleb.
вот с этим позволю себе не согласиться. Да, исключение штука
тяжеловесная на С++ (раскрутка стека в основном), но по выходу из
функции как ни крути эти действия совершаются. Это раз. В .NET нет
раскрутки стека как таковой (если конечно нет finally с вызовом Dispose
и т.п.). Так что исключение там — довольно легковесный механизм.
Вопрос стоит, по большому счету, в идее и в том, в какую сторону этот
код потом будет расти, чтобы выбранный механизм не стоял на пути
расширяемости, внесения ожидаемых изменений и т.п.
Здравствуйте, GlebZ, Вы писали:
GZ>2. Ошибка — объект или группа объектов не смогла выполнить операцию и корректно сообщило об этом. Ситуация восстановимая для внешней логики.
Вот это мне непонятно. Что значит ситуация восстановима для внешней логики? Откуда объекту знать восстановима она для внешней логики или нет? Операция не может быть выполнена, всё, точка. Делать предположения о логике работы внешних объектов — значит намертво к ним привязываться.
GZ>3. Фатальная ошибка — программа, или некоторая подсистема не может далее выполняться и находится в невосстановимом состоянии.
Две ситуации.
1. Не могу открыть соединение к базе данных (фатальная ошибка).
2. Не могу добавить запись по причине дублирования значения одного из полей (например, совпал логин пользователя).
Это по твоему одинаковые ситуации или разные? По мне так разницы нет. В обоих случаях программа не может продолжить дальнейшее выполнение. Да, во втором случае пользователь может исправить ситуацию. Но это будет уже новый цикл выполнения операции, который с первым абсолютно никак не должен быть связан. Точно так же я могу сказать, что и в первом случае админ может поднять базу данных и все пойдёт своим чередом. Т.е. разницы между фатальной ошибкой и ошибкой ввода пользователя я не вижу. Совсем. По крайней мере логика моих программ по отношению к ним одинакова. Может быть отличается способ отображения ошибки пользователю, но это всё легко реализуется с помошью типизации исключений.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Не хочется обощать задачу, поэтому приблизительно описываю свою ситуацию.
Есть генератор докуметов, на входе данные, на выходе документ, документ не
всегда может быть "хорошо сгенерирован" (например, слишком большая
картинка,
которая не влазит, не соответсвует размерам страницы или таблицы), нужно
передавать эту информацию в вызывающий контекст, для внутренней реализации
решение есть, не знаю как это лучше сделать в фасаде генератора.
Вариант 1:
Generator generator = new Generator()
....
try
{
Result result = generator.gentrate(data, outStream);
if(result.hasWarnings())
{
.....
}
}
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, achmed, Вы писали:
A>>Может быть exception ?
IT>Почему бы и нет? Всё таки коды возврата — это прошлый век.
IMHO для такой задачи эксепшн кидать не кузяво.
Лучше отдавай назад коллекцию предупреждений/ошибок возникших при отработке.
Здравствуйте, migel, Вы писали:
IT>>Почему бы и нет? Всё таки коды возврата — это прошлый век. M>IMHO для такой задачи эксепшн кидать не кузяво. M>Лучше отдавай назад коллекцию предупреждений/ошибок возникших при отработке.
Вообще-то эксепшин — это объектно-ориентированный код возврата, что тут некузявого. Видел приложения использующие COM без всяких обёрток? Обработка кодов возврата там занимает большую часть кода. Данный пример очень простой, но даже на нём мы имеем 5 строчек кода вместо одной. А стоит ему только чуть-чуть усложниться как усложнится и логика обработки кодов возврата. Вместо двух строчек бизнес логики мы будем иметь 10 строк непонятно чего. В общем, коды возврата sux в любых своих проявлениях.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, migel, Вы писали:
IT>>>Почему бы и нет? Всё таки коды возврата — это прошлый век. M>>IMHO для такой задачи эксепшн кидать не кузяво. M>>Лучше отдавай назад коллекцию предупреждений/ошибок возникших при отработке.
IT>Вообще-то эксепшин — это объектно-ориентированный код возврата, что тут некузявого. Видел приложения использующие COM без всяких обёрток?
Видел, и? IT>Обработка кодов возврата там занимает большую часть кода.
И это не вызыфвает возражений IT>Данный пример очень простой, но даже на нём мы имеем 5 строчек кода вместо одной. А стоит ему только чуть-чуть усложниться как усложнится и логика обработки кодов возврата. Вместо двух строчек бизнес логики мы будем иметь 10 строк непонятно чего. В общем, коды возврата sux в любых своих проявлениях.
Во первых никаких кодов я не заметил — есть нормальный объект — результат операции. Насколько я понял результат может состоять из множества предупреждений и ошибок. И вот именно в такой постановке задачи исключения совершенно не подходят.
Здравствуйте, migel, Вы писали:
IT>>Вообще-то эксепшин — это объектно-ориентированный код возврата, что тут некузявого. Видел приложения использующие COM без всяких обёрток? M>Видел, и?
Жуть!
IT>>Обработка кодов возврата там занимает большую часть кода. M>И это не вызыфвает возражений
Странно. У меня вызывает не только возражение, но и отвращение
M>Во первых никаких кодов я не заметил — есть нормальный объект — результат операции.
Какая разница объект это или не объект. Пусть это будет объект возврата. Ключевое слово здесь 'возврата'. Я должен обработать этот код сразу после его получения и в том же месте где я его получил. В случае вложенных вызовов я должен протолкнуть его наверх и так по всем уровням.
M>Насколько я понял результат может состоять из множества предупреждений и ошибок. И вот именно в такой постановке задачи исключения совершенно не подходят.
Очень даже хорошо подходят. Положи тот же самый объект в исключение и разницы в функциональности не будет никакой.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
IT wrote: > Здравствуйте, migel, Вы писали: > M>Во первых никаких кодов я не заметил — есть нормальный объект — результат операции. > Какая разница объект это или не объект. Пусть это будет объект возврата. Ключевое слово здесь 'возврата'. Я должен обработать этот код сразу после его получения и в том же месте где я его получил. В случае вложенных вызовов я должен протолкнуть его наверх и так по всем уровням.
Я пожалуй соглашусь с migel'ем: исключение — это ОШИБОЧНАЯ ситуация, при
которой нет возможности продолжить работу. Это не ожидаемая ситуация,
которую нужно просто определенным образом разрулить, как это происходит
в этом случае. Ведь по сути, нужно просто выяснить, были ли какие-нибудь
проблемы с генерацией документа. Вот если его не удалось сгенерировать
(например, картинка в некорректном формате) — вот тут скорее всего
исключение. А если удалось, но не красиво, то нет исключения: успех да и
только.
Так что в описанной ситуации я бы использовал 1-й вариант: он более
понятный чем 2-й (если конечно не введено уже понятие контекста,
используемое для этих целей).
Всем спасибо за советы/
Cогласен по поводу exception, exception — это ошибка.
Вспомним COM, все методы всех интерфейсов возвращают HRESULT, для
чтобы облегчить жизнь, используются врапперы (директива #import, comet),
примерно так
HRESULT hr = pStream->Read(.....)
if(FAILED(hr))
throw com_excpetion(hr,pStream);
// и никаких exception для SUCCEEDED(hr)
exception — это замены коду ошибки (но не коду возврата) в
обьектно-ориентированном
стиле в общем стиле, так пишут в умных книгах .
Придумал, хотя нет, вспомнил еще один вариант, подходящий к данной
ситуации — callback нитерфейс.
achmed wrote: > Придумал, хотя нет, вспомнил еще один вариант, подходящий к данной > ситуации — callback нитерфейс. > [code] > Generator generator = new Generator() > WaringsListenerImpl listener = new WaringsListenerImpl(); > generator.setWaringsListener(listener)ж > .... > try > { > generator.gentrate(data, outStream); > if(listener.hasWarnings()) > { > ..... > } > } > [code]
мое скромное ИМХО: этот код не очевиден для читающего. И это при том,
что слушалка (а по сути притянутая за уши реализация Visitor) по сути
тут не нужна, разве что тебе нужно своим кодом отслеживать события в
объекте, хрен знает как болтающемся в приложении. А тут все просто: один
вызов. Хоть туда слушалку передавай, как с контекстом. Вот если у тебя
стоит задача, что, например, слушалка слушает и управляет процессом
генерации (например, по накоплении 5 предупреждений просто сообщает о
необходимости прервать генерацию, вот это другое дело. В твоем случае,
ИМХО опять же, стоит вернуть коллекцию ворнингов и не париться.
Здравствуйте, Козьма Прутков, Вы писали:
КП>Я пожалуй соглашусь с migel'ем: исключение — это ОШИБОЧНАЯ ситуация, при которой нет возможности продолжить работу.
А разве это не так? Что тогда подразумевается под "документ не всегда может быть "хорошо сгенерирован" (например, слишком большая картинка,"? Я это понял как не может быть сгенерирован.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
IT wrote: > Здравствуйте, Козьма Прутков, Вы писали: > > КП>Я пожалуй соглашусь с migel'ем: исключение — это ОШИБОЧНАЯ ситуация, при которой нет возможности продолжить работу. > > А разве это не так? Что тогда подразумевается под "документ не всегда может быть "хорошо сгенерирован" (например, слишком большая картинка,"? Я это понял как не может быть сгенерирован.
а я понял, что он сгенерирован, но "не хорошо" Типа, жить можно, но
картинка вылазит за пределы страницы... Ручками придется поправить или
еще что-то.
Здравствуйте, Козьма Прутков, Вы писали:
КП>а я понял, что он сгенерирован, но "не хорошо" Типа, жить можно, но картинка вылазит за пределы страницы... Ручками придется поправить или еще что-то.
Типа чуть-чуть беременный... Понял
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>А разве это не так? Что тогда подразумевается под "документ не всегда может быть "хорошо сгенерирован" (например, слишком большая картинка,"? Я это понял как не может быть сгенерирован.
Одно из моих личных IMHO.
Производители компиляторов (по крайней мере С++ и JIT) так старались чтобы исключительные ситуации были исключительными по самые уши. То бишь обработки их более чем тормозные. Поэтому, если можно обработать (а практически всегда можно) ошибки логикой и не доводить до исключения, то их нужно обрабатывать логикой. Исключения нужны только для отладки.
Здравствуйте, Козьма Прутков, Вы писали:
КП>вот с этим позволю себе не согласиться. Да, исключение штука КП>тяжеловесная на С++ (раскрутка стека в основном), но по выходу из КП>функции как ни крути эти действия совершаются. Это раз. В .NET нет КП>раскрутки стека как таковой (если конечно нет finally с вызовом Dispose КП>и т.п.). Так что исключение там — довольно легковесный механизм.
В НЕТ генерация Exception очень тяжелая операция. Среда на выполнении просматривает стек куда надо переместиться, и заполняет объект Exception (который обязан быть по стандарту CLS) в том числе информацие о всем стеке. КП>Вопрос стоит, по большому счету, в идее и в том, в какую сторону этот КП>код потом будет расти, чтобы выбранный механизм не стоял на пути КП>расширяемости, внесения ожидаемых изменений и т.п.
Расширять с помощью exception — накладное дело. Нет ничего более постоянного чем временно. Тут нужна явная обработка ошибок (или неожиданностей). Мне больше нравится второй вариант. В этом случае, по выбору каждый механизм сможет обработать те или иные особенности по своему выбору. Ну а кто-нибудь может сказать(пометить), что контекст не является достойным для вывода. Ну и обработать эту пометку на каком-то этапе.
Здравствуйте, GlebZ, Вы писали:
GZ>Производители компиляторов (по крайней мере С++ и JIT) так старались чтобы исключительные ситуации были исключительными по самые уши. То бишь обработки их более чем тормозные. Поэтому, если можно обработать (а практически всегда можно) ошибки логикой и не доводить до исключения, то их нужно обрабатывать логикой. Исключения нужны только для отладки.
При таком подходе код из бизнес логики очень легко превращается в логику обработки кодов возвратов и проталкивания их наверх, особенно при глубокой вложенности вызовов.
Есть очень простое правило. Исключения не должны использоваться в логике работы программы. Т.е. тогда, когда результат ошибки ожидаем программой и может быть ею исправлен, либо использован другой путь для дальнейших вычислений. Если же программа не может продолжить нормальное выполнение, то должно быть сгенерировано исключение. При таком подходе количество исключений в системе минимально. Например, елси приложение взаимодействует с пользователем. То исключение может произойти единовременно в момент воздействия пользователя на систему. Если это сервис или сервер приложений, то одно исключение на выполняемую операцию. Грубо говоря "смогла / не смогла". В этом случае тормозами исключений можно пренебречь.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Exception в этом случае не годится. Потому что exception, если его не поймать, нарушит штатный ход работы вызывающего кода. А поймать можно забыть. Да и вызывающий код может быть разный — в каких-то случаях эта информация нужна, в каких-то нет. Придется везде лоывить этот exception и .. тут же пропускать. Очень некрасиво.
Имхо: если это единичный случай — вернуть класс с информацией о результатах генерации. Если такие вещи нужны много где и по каким-то причинам не хочется засорять прототипы этими классами — придумывать механизм, который будет переносить подобную информацию от "серверного" кода в "клиентский" параллельно обычным возвращаемым значениям, через какие-то контексты и т.п.
Здравствуйте, Igor Trofimov, Вы писали:
iT>Exception в этом случае не годится. Потому что exception, если его не поймать, нарушит штатный ход работы вызывающего кода. А поймать можно забыть.
А если в стриме место закончилось и ты забыл поймать исключение, то это нормально?
iT>Да и вызывающий код может быть разный — в каких-то случаях эта информация нужна, в каких-то нет. Придется везде лоывить этот exception и .. тут же пропускать.
А это ещё зачем? Вся прелесть исключений в том, что если тебе не надо, то не лови, и в простейшем случае на визуальную форму тебе понадобится один блок try / catch. В ASP.NET даже и этого не надо, достаточно определить страницу для вывода ошибки.
iT>Очень некрасиво.
Забыть обработать код возврата ещё легче. Более того, это не просто некрасиво, это ещё и очень опасно. Это потенциальный источник таких проблем, которые могут не всплыть ни при разработк ни при тестировании. Ловить их очень трудно, а поймав, приходится долго разбираться в коде, чтобы понять как так внести изменения, чтобы ничего не сломать.
На самом деле, чтобы не уйти во флейм нам нужен ответ автора топика на вопрос — большая картинка для него это штатная ожидаемая ситуация или нет, может ли он после этого продолжить работу?
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>При таком подходе код из бизнес логики очень легко превращается в логику обработки кодов возвратов и проталкивания их наверх, особенно при глубокой вложенности вызовов.
Почти точно. Только обычно, это управляется состоянием объектов задействованных в логике. И в зависимости от их состояния логика и управляется. А ошибка, всего лишь часть состояния.
IT>Есть очень простое правило. Исключения не должны использоваться в логике работы программы. Т.е. тогда, когда результат ошибки ожидаем программой и может быть ею исправлен, либо использован другой путь для дальнейших вычислений. Если же программа не может продолжить нормальное выполнение, то должно быть сгенерировано исключение. При таком подходе количество исключений в системе минимально. Например, елси приложение взаимодействует с пользователем. То исключение может произойти единовременно в момент воздействия пользователя на систему. Если это сервис или сервер приложений, то одно исключение на выполняемую операцию. Грубо говоря "смогла / не смогла". В этом случае тормозами исключений можно пренебречь.
Согласен. В некоторых случаях это необходимо(еще пример пересылка ошибки через remoting, SOAP, rollback). Но тут есть еще некоторый момент кроме тормознутости. Включение исключений в логику нарушает инкапсуляцию этой логики. Если класс(модуль) используется во многих местах, и его логика надеется что исключение будет обработано, то тут может быть и обломс. В этом виде мне нравится подход Java к документированию исключений в декларации метода.
Замечательная вещь была встречена в Oracle, когда он сообщал о том, что до протухания пароля осталось столько-то времени через ошибку при коннекте. В результате, нужно тебе это, или не нужно, это приходилось учитывать.
IT пишет:
> > На самом деле, чтобы не уйти во флейм нам нужен ответ автора топика на > вопрос — большая картинка для него это штатная ожидаемая ситуация или > нет, может ли он после этого продолжить работу? >
Да, это ожидаемая ситуация, при которой генератор должен продолжить свою
работу, но
известить об этом контекст, в точности как варнинги компилятора, мне
казалось, что я
с самого начало это обьяснил, в следующий раз постраюсь выражаться яснее.
Здравствуйте, achmed, Вы писали:
A>Да, это ожидаемая ситуация, при которой генератор должен продолжить свою работу, но известить об этом контекст, в точности как варнинги компилятора, мне казалось, что я с самого начало это обьяснил, в следующий раз постраюсь выражаться яснее.
Понятно. Тогда исключение здесь по-любому не применимо. Забираю все свои советы обратно
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, GlebZ, Вы писали:
GZ>Почти точно. Только обычно, это управляется состоянием объектов задействованных в логике. И в зависимости от их состояния логика и управляется. А ошибка, всего лишь часть состояния.
Вот я вот этого не понимаю. Если ошибка — это нормальное состояние, то почему мы называем её ошибкой. Уберём путанницу из терминологии и всё сразу станет на свои места.
GZ>Согласен. В некоторых случаях это необходимо(еще пример пересылка ошибки через remoting, SOAP, rollback). Но тут есть еще некоторый момент кроме тормознутости. Включение исключений в логику нарушает инкапсуляцию этой логики. Если класс(модуль) используется во многих местах, и его логика надеется что исключение будет обработано, то тут может быть и обломс.
Логике компонента должно быть по барабану, обработают её исключение или нет. Это проблема вызывающего метода. Ты же не думаешь, что разработчики класса SqlConnection очень озабачивались будут или нет обработываться их исключения. К тому же, ещё раз повторюсь, необработать возвращаемое значение в тысячу раз легче, а вот найти в коде такое место в тысячу раз сложнее.
GZ> В этом виде мне нравится подход Java к документированию исключений в декларации метода.
Если не ошибаюсь, если я не хочу обрабатывать исключение в вызываемом методе, а хочу просто прокинуть его выше, то я всё равно должен буду его поймать, а потом поновой выкинуть. Или я ошибаюсь? Если так, то это портит всю идею.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
IT пишет:
> GZ> В этом виде мне нравится подход Java к документированию исключений > в декларации метода. > > Если не ошибаюсь, если я не хочу обрабатывать исключение в вызываемом > методе, а хочу просто прокинуть его выше, то я всё равно должен буду > его поймать, а потом поновой выкинуть. Или я ошибаюсь? Если так, то > это портит всю идею. >
Нет, нужно добавить в вызывающий метод спецификацию исклющения, которое
"не хочется ловить".
IT>А если в стриме место закончилось и ты забыл поймать исключение, то это нормально?
Это нештатная ситуация и то, что она будет обработана стандартным системным обработчиком исключений — верно.
Аналогичная обработка для случая, описанного achmed'ом — неверна, имхо.
IT>А это ещё зачем? Вся прелесть исключений в том, что если тебе не надо, то не лови, и в простейшем случае на визуальную форму тебе понадобится один блок try / catch. В ASP.NET даже и этого не надо, достаточно определить страницу для вывода ошибки.
То-то и оно что характер этой "ошибки" другой — см. название топика — "система предупреждений". Нужно всего-лишь уведомить вызывающий код или пользователя о том, что результат, возможно, неадекватен. Это вполне может быть тот самый результат, который нужен и продолжать работу можно и нужно. В отличие от закончившегося стрима.
IT>Забыть обработать код возврата ещё легче.
Абсолютно! Поэтому его нельзя применять для возвратов, которые могут оказаться критичны. Это не тот случай.
IT>На самом деле, чтобы не уйти во флейм нам нужен ответ автора топика на вопрос — большая картинка для него это штатная ожидаемая ситуация или нет, может ли он после этого продолжить работу?
Предполагаю ответ — это может быть штатной ситуацией Это например, решает конкретный пользователь в конкретном случае, увидев предупреждение и посмотрев глазами на рузельтат. Система помогает заметить поведение, которое может быть неверным.
Здравствуйте, IT, Вы писали:
IT>Вот я вот этого не понимаю. Если ошибка — это нормальное состояние, то почему мы называем её ошибкой. Уберём путанницу из терминологии и всё сразу станет на свои места.
Просто нужно разделить на ворнинги, ошибки и фатальные ошибки. Тогда станет легче.
IT>Логике компонента должно быть по барабану, обработают её исключение или нет. Это проблема вызывающего метода. Ты же не думаешь, что разработчики класса SqlConnection очень озабачивались будут или нет обработываться их исключения. К тому же, ещё раз повторюсь, необработать возвращаемое значение в тысячу раз легче, а вот найти в коде такое место в тысячу раз сложнее.
На уровне программиста? Не надо. Сообщение о том что "произошла неожиданная ошибка. Table А was locked"(пишу ессно из головы) сразу же приводит к тормошению разработчиков со строны клиентов и сопровождения. В данном виде две вещи, почему ошибка неожиданная, и почему название нерусское(есть у нас такая проблема географии). А это значит, что вызывающий должен думать не о последствиях, а предотвращать причину. Может это и не всегда возможно, но надо к этому стремится.
Во вторых, ты говоришь о возвращаемых значениях, что совсем плохо (поскольку имеют тенденцию необрабатываться). По настоящему, объекты обязаны генерить исключения. Чтобы программисту было понятно что произошло, и как это предотвращать. А вот для этого, нужна некоторая корректная информация о состоянии объекта.
IT>Если не ошибаюсь, если я не хочу обрабатывать исключение в вызываемом методе, а хочу просто прокинуть его выше, то я всё равно должен буду его поймать, а потом поновой выкинуть. Или я ошибаюсь? Если так, то это портит всю идею.
Нет. Просто в описании процедуры ты обязан прописать какие исключения можно из нее получить. Мне такой подход очень нравится, но судя по всему, отношение к нему неравнозначное. Есть ярые противники, есть явные сторонники этого подхода. Но вообще, у них были проблемы (и по моему остаются) потому как, когда Java замысливалась когда исключения были чрезвычайно популярны. Поэтому у них на элементарных операциях они выбрасываются. Некоторые на стенку от этого лезли. Может это уже все изменилось.
Здравствуйте, GlebZ, Вы писали:
IT>>Вот я вот этого не понимаю. Если ошибка — это нормальное состояние, то почему мы называем её ошибкой. Уберём путанницу из терминологии и всё сразу станет на свои места. GZ>Просто нужно разделить на ворнинги, ошибки и фатальные ошибки. Тогда станет легче.
Вот видишь как всё сложно? Смешались в кучу кони, люди... Ворнинги, ошибки, фатальные ошибки... А может всё проще? Просто — ошибка / не ошибка? А то получается, что фатальная ошибка — это очень страшная ошибка, просто ошибка — ошибка, но не страшная. Ворнинг — вообще непонятно, типа немножко ошибка, немножко не ошибка.
IT>>Логике компонента должно быть по барабану, обработают её исключение или нет. Это проблема вызывающего метода. Ты же не думаешь, что разработчики класса SqlConnection очень озабачивались будут или нет обработываться их исключения. К тому же, ещё раз повторюсь, необработать возвращаемое значение в тысячу раз легче, а вот найти в коде такое место в тысячу раз сложнее. GZ>На уровне программиста? Не надо. Сообщение о том что "произошла неожиданная ошибка. Table А was locked"(пишу ессно из головы) сразу же приводит к тормошению разработчиков со строны клиентов и сопровождения. В данном виде две вещи, почему ошибка неожиданная, и почему название нерусское(есть у нас такая проблема географии). А это значит, что вызывающий должен думать не о последствиях, а предотвращать причину. Может это и не всегда возможно, но надо к этому стремится.
В данном случае ты вообще говоришь о баге. Т.е. по твоей классификации мы уже имеем — ворнинг, ошибка, фатальная ошибка, баг. Что ещё?
GZ>Во вторых, ты говоришь о возвращаемых значениях, что совсем плохо (поскольку имеют тенденцию необрабатываться). По настоящему, объекты обязаны генерить исключения. Чтобы программисту было понятно что произошло, и как это предотвращать. А вот для этого, нужна некоторая корректная информация о состоянии объекта.
Ну допустим есть у меня информация об объекте — объект не валидный, т.к. не заполнено обязательное поле, что ты будешь делать?
GZ>Нет. Просто в описании процедуры ты обязан прописать какие исключения можно из нее получить. Мне такой подход очень нравится, но судя по всему, отношение к нему неравнозначное. Есть ярые противники, есть явные сторонники этого подхода.
Это вполне естественно. Как теоретик я только за такой подход. Всё очень логично и красиво. Но как практик, я понимаю, что это принесёт мне кучу головной боли, т.к. это только усложнит мой процесс разарботки.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>>>Вот я вот этого не понимаю. Если ошибка — это нормальное состояние, то почему мы называем её ошибкой. Уберём путанницу из терминологии и всё сразу станет на свои места. GZ>>Просто нужно разделить на ворнинги, ошибки и фатальные ошибки. Тогда станет легче.
IT>Вот видишь как всё сложно? Смешались в кучу кони, люди... Ворнинги, ошибки, фатальные ошибки... А может всё проще? Просто — ошибка / не ошибка? А то получается, что фатальная ошибка — это очень страшная ошибка, просто ошибка — ошибка, но не страшная. Ворнинг — вообще непонятно, типа немножко ошибка, немножко не ошибка.
Да уж. С классификацией не фонтан. Попытаюсь дать определения:
1. Ворнинг — на уровне выполнения такого не бывает. Вглюкнул.
2. Ошибка — объект или группа объектов не смогла выполнить операцию и корректно сообщило об этом. Ситуация восстановимая для внешней логики.
3. Фатальная ошибка — программа, или некоторая подсистема не может далее выполняться и находится в невосстановимом состоянии.
GZ>>На уровне программиста? Не надо. Сообщение о том что "произошла неожиданная ошибка. Table А was locked"(пишу ессно из головы) сразу же приводит к тормошению разработчиков со строны клиентов и сопровождения. В данном виде две вещи, почему ошибка неожиданная, и почему название нерусское(есть у нас такая проблема географии). А это значит, что вызывающий должен думать не о последствиях, а предотвращать причину. Может это и не всегда возможно, но надо к этому стремится.
IT>В данном случае ты вообще говоришь о баге. Т.е. по твоей классификации мы уже имеем — ворнинг, ошибка, фатальная ошибка, баг. Что ещё?
С какой стороны посмотреть. С одной стороны это фатальная ошибка. С другой стороны, это также называется падучая программа(неважно полностью процесс падает, или часть его). Ну а падучую программу надо исправлять, и переводить в состояние непадучести.
IT>Ну допустим есть у меня информация об объекте — объект не валидный, т.к. не заполнено обязательное поле, что ты будешь делать?
Объект должен отвечать на любую мессагу эксцепшеном. Пока вызываемающий не восстановит его состояние.
IT>Это вполне естественно. Как теоретик я только за такой подход. Всё очень логично и красиво. Но как практик, я понимаю, что это принесёт мне кучу головной боли, т.к. это только усложнит мой процесс разарботки.
Зато упростит для других использование и корректную обработку ошибок. Иногда подобной информации очень сильно не хватает.
С уважением, Gleb.
PS: вообще-то я глянул свой код, и понял что в некотором смысле неправ. Винюсь. Расстреляейте меня. Ситуаций с полезностью эксцепшенов несколько больше.
Здравствуйте, IT, Вы писали: IT>Хорошо хоть так. Хотя тоже не фонтан. Если я меняю декларацию, то надо менять всё по цепочке вверх
именно поэтому в Net от этого отказались. Слишком легко нарушить этот контракт, выкинув RuntimeException, и слишком много геморроя с каскадными изменениями.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, IT, Вы писали:
IT>Вот это мне непонятно. Что значит ситуация восстановима для внешней логики? Откуда объекту знать восстановима она для внешней логики или нет? Операция не может быть выполнена, всё, точка. Делать предположения о логике работы внешних объектов — значит намертво к ним привязываться.
Предположение в том, что я не могу продолжить работу и буду выкидывать exception по любому поводу связанному с ошибкой? Это это знание своей логики и предположение что внешнему объекту возможно так надо.
IT>Две ситуации.
IT>1. Не могу открыть соединение к базе данных (фатальная ошибка). IT>2. Не могу добавить запись по причине дублирования значения одного из полей (например, совпал логин пользователя).
IT>Это по твоему одинаковые ситуации или разные? По мне так разницы нет. В обоих случаях программа не может продолжить дальнейшее выполнение. Да, во втором случае пользователь может исправить ситуацию. Но это будет уже новый цикл выполнения операции, который с первым абсолютно никак не должен быть связан. Точно так же я могу сказать, что и в первом случае админ может поднять базу данных и все пойдёт своим чередом. Т.е. разницы между фатальной ошибкой и ошибкой ввода пользователя я не вижу. Совсем. По крайней мере логика моих программ по отношению к ним одинакова. Может быть отличается способ отображения ошибки пользователю, но это всё легко реализуется с помошью типизации исключений.
В этом разница конечно есть. Вторую ситуацию можно недопускать.
Но в остальном ты прав. Я и написал в PS что раскаиваюсь. Я сходу не учел одну вещь. Есть две фатальных системы — внешняя система которая имеет тенденцию пересылать весьма неожиданные ошибки в том числе на аппаратном уровне, которые не особо и обработаешь. Ну и вторая — это приложение к компу в виде пользователя. Существует достаточно много решений, в которых реакция пользователя предсказать невозможно. Или допустим редактирование конфигурационного файла в ручную. В общем, либо включать исключения в логику, либо убирать пользователя
Здравствуйте, GlebZ, Вы писали:
IT>>Логике компонента должно быть по барабану, обработают её исключение или нет. Это проблема вызывающего метода. Ты же не думаешь, что разработчики класса SqlConnection очень озабачивались будут или нет обработываться их исключения. К тому же, ещё раз повторюсь, необработать возвращаемое значение в тысячу раз легче, а вот найти в коде такое место в тысячу раз сложнее. GZ>На уровне программиста? Не надо. Сообщение о том что "произошла неожиданная ошибка. Table А was locked"(пишу ессно из головы) сразу же приводит к тормошению разработчиков со строны клиентов и сопровождения. В данном виде две вещи, почему ошибка неожиданная, и почему название нерусское(есть у нас такая проблема географии). А это значит, что вызывающий должен думать не о последствиях, а предотвращать причину. Может это и не всегда возможно, но надо к этому стремится.
Это все красиво, но всетаки не работает. Ну во-первых, было предложение тот же объект завернуть в ИС и пулять на верх. И что тогда? Тогда выходит уже, что вместо кодов возврата прийдется перехватывать и глушить варнинги! Причем тут уже в каждом месте. Во-вторых, как вы себе представляете процесс генерации ИС с варнингом и при этом всем доработке процедуры до конца! Тут с логикой ИМХО совсем напряг будет — так что думаю к этому моменту прозрачность и две строки кода вместо десяти ушли в сад.
GZ>Во вторых, ты говоришь о возвращаемых значениях, что совсем плохо (поскольку имеют тенденцию необрабатываться). По настоящему, объекты обязаны генерить исключения. Чтобы программисту было понятно что произошло, и как это предотвращать. А вот для этого, нужна некоторая корректная информация о состоянии объекта.
хм... узко мыслим. почему собственно объекта? почему не системы? попробуй представь такое: процесс принял на обработку объекты А и Б. Они не согласуются. Кто не корректен? Конечно же предусловие к процессу. А почему?... а я и сам не знаю, мож А не корректен, мож Б, а может текущее состояние системы. Для исключения слишком хитрая и главное (к чему я веду) конкретная ситуация. т.е. как уже упоминалось выше — конкретные ситуации следует разруливать на кодах возврата (ну может не на кодах, а на объектах, просто принятая терминология).
IT>>Если не ошибаюсь, если я не хочу обрабатывать исключение в вызываемом методе, а хочу просто прокинуть его выше, то я всё равно должен буду его поймать, а потом поновой выкинуть. Или я ошибаюсь? Если так, то это портит всю идею.
интересная конструкция будет — try->catch->ex.add("А у меня тоже варнинг!")->throw... а потом на верху пусть ищут ошибки и варнинги
всетаки ИС — это когда процедура как бы не доработала до конца...
в догонку из моей практики:
есть две перекрестные сущности, определенная пара (например А(2) и Б(7)) перед началом работы запрашивает у менеджера блокирующий объект, так что если вдруг другие А(2), Б(7) захотят тоже работать — им объект не предоставят. так называемый у меня LockObject. так вот, если объект не может быть предоставлен — я раньше генерил исключение... функциональность развивалась, и появились ситуации, когда вот такие запросы блокирующего объекта валят с невероятной скоростью из разных потоков! жить то оно жило, но как оказалось ооочень тяжело очищать стек в таком количестве из разных потоков. Быстренько договорились что вместо ИС будет nil и все залетало! если интересует статистика — тестовые данные до ~57сек после ~700мсек!!! а вы говорите идеология! я после этого кинулся весь код пересматривать где бы еще от ИС отказаться (конечно не в ущерб логике).
Здравствуйте, Козьма Прутков, Вы писали:
КП>Вот если у тебя КП>стоит задача, что, например, слушалка слушает и управляет процессом КП>генерации (например, по накоплении 5 предупреждений просто сообщает о КП>необходимости прервать генерацию, вот это другое дело. В твоем случае, КП>ИМХО опять же, стоит вернуть коллекцию ворнингов и не париться.
хм... наверное я уже не могу мыслить на уровне обычной задачи...
я бы лично не задумываясь выбрал контекст, т.к. его всегда удобно передать удаленно
и еще, контекст как бы подразумевает, что в него можно что-то добавить или из него что-то удалить. имея же колекцию варнигов, что-то удалять рука не поднимется (опять ИМХО). а ведь вызывающий объект может пару-тройку ошибок обработать самостоятельно не тревожа клиента и убрать их из контекста.