Здравствуйте, 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: вообще-то я глянул свой код, и понял что в некотором смысле неправ. Винюсь. Расстреляейте меня. Ситуаций с полезностью эксцепшенов несколько больше.
Здравствуйте, GlebZ, Вы писали:
GZ>2. Ошибка — объект или группа объектов не смогла выполнить операцию и корректно сообщило об этом. Ситуация восстановимая для внешней логики.
Вот это мне непонятно. Что значит ситуация восстановима для внешней логики? Откуда объекту знать восстановима она для внешней логики или нет? Операция не может быть выполнена, всё, точка. Делать предположения о логике работы внешних объектов — значит намертво к ним привязываться.
GZ>3. Фатальная ошибка — программа, или некоторая подсистема не может далее выполняться и находится в невосстановимом состоянии.
Две ситуации.
1. Не могу открыть соединение к базе данных (фатальная ошибка).
2. Не могу добавить запись по причине дублирования значения одного из полей (например, совпал логин пользователя).
Это по твоему одинаковые ситуации или разные? По мне так разницы нет. В обоих случаях программа не может продолжить дальнейшее выполнение. Да, во втором случае пользователь может исправить ситуацию. Но это будет уже новый цикл выполнения операции, который с первым абсолютно никак не должен быть связан. Точно так же я могу сказать, что и в первом случае админ может поднять базу данных и все пойдёт своим чередом. Т.е. разницы между фатальной ошибкой и ошибкой ввода пользователя я не вижу. Совсем. По крайней мере логика моих программ по отношению к ним одинакова. Может быть отличается способ отображения ошибки пользователю, но это всё легко реализуется с помошью типизации исключений.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, 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 предупреждений просто сообщает о КП>необходимости прервать генерацию, вот это другое дело. В твоем случае, КП>ИМХО опять же, стоит вернуть коллекцию ворнингов и не париться.
хм... наверное я уже не могу мыслить на уровне обычной задачи...
я бы лично не задумываясь выбрал контекст, т.к. его всегда удобно передать удаленно
и еще, контекст как бы подразумевает, что в него можно что-то добавить или из него что-то удалить. имея же колекцию варнигов, что-то удалять рука не поднимется (опять ИМХО). а ведь вызывающий объект может пару-тройку ошибок обработать самостоятельно не тревожа клиента и убрать их из контекста.