Как я могу сообщить Delphi, что уже обработал исключение? - PullRequest
6 голосов
/ 05 августа 2009

Я установил Application.OnException для пользовательского обработчика исключений, чтобы я мог регистрировать сбои и давать возможность выхода. Однако теперь я обнаружил, что это работает даже для исключений, которые я уже обработал, например, исключений, которые возникают при проверке числовых входов. Есть ли способ заставить обработчик пользовательских исключений работать только с необработанными исключениями?

Изменить: оказывается, что я получаю ожидаемое поведение, когда я запускаю вне отладчика. Может быть, это просто отладчик. Я не считаю взаимодействие отладчика Delphi с исключениями интуитивно понятным, если не сказать больше.

Ответы [ 4 ]

14 голосов
/ 05 августа 2009

Если поведение изменяется внутри и снаружи отладчика, то на самом деле не ваша программа говорит вам об исключениях. Я написал об этом явлении на моем веб-сайте:

Почему я продолжаю получать сообщения об ошибках даже после написания обработчика исключений?

Выдержка:

В своих настройках по умолчанию IDE Delphi уведомляет вас о возникновении исключения в вашей программе .... Важно понимать, что на данный момент нет кода обработки вашей программы еще не запущен. Это все сам Delphi; его особый статус отладчика позволяет ему получать первое уведомление о любом исключении в вашей программе, даже до того, как ваша программа узнает об этом.

После того, как вы отклоните окно сообщения Delphi, выполнение будет приостановлено на лучшей строке вашего исходного кода, которую Delphi может найти в качестве источника исключения. Нажмите кнопку «Выполнить», чтобы возобновить работу вашей программы. Контроль перейдет к следующему окончательно или кроме блок. Прежде чем вы возобновите свою программу, вы можете использовать различные инструменты отладки в вашем распоряжении. Вы можете проверить значения любых переменных в области видимости и даже изменить их значения.

Итак, как вы уведомляете Delphi, что вы уже обработали исключение? Вы этого не сделаете - потому что ваша программа еще не обработала ее . И почему отладчик не может определить, собирается ли ваша программа обработать исключение? Потому что для этого нужно выполнить вашу программу дальше. Обнаружение отсутствия обработчика исключений похоже на решение проблемы остановки. Единственный способ определить, будет ли обрабатываться исключение, - это запустить программу и посмотреть, будет ли обработано исключение. Но к этому моменту уже слишком поздно делать какую-либо отладку, поэтому у отладчика нет иного выбора, кроме как приостановить вашу программу, когда он сначала обнаруживает исключение, а затем позволяет вам выяснить, что делать дальше.

Моя статья описывает некоторые способы, которые позволяют избежать отладчика перехвата определенных исключений, кратко изложенные здесь:

  • Используйте расширенные контрольные точки , чтобы временно отключить исключения для определенных областей кода.
  • Настройте отладчик на игнорирование определенных классов исключений (и их потомков).
  • Скажите отладчику не уведомлять вас о любых исключениях.
  • Отключить встроенную отладку в целом.

Есть еще один вариант, который я не включил в свою статью:

  • Измените вашу программу так, чтобы исключение не возникало в первую очередь.

Вы говорите, что проверяете числовой ввод. Мне кажется, что вы делаете что-то вроде вызова StrToInt, а затем перехватываете исключение EConvertError, когда ввод не является действительным целым числом. Это дорогой способ проверки ввода. Вместо этого используйте TryStrToInt, который сообщит вам, успешно ли выполнено преобразование, или StrToIntDef, который вернет значение по умолчанию, а не вызовет исключение. Другой вариант - просто старый Val, который пытается преобразовать строку, и в случае неудачи он сообщает, какая позиция в строке вызвала сбой. Val особенно полезно, если вы хотите использовать как можно больше символов для преобразования, а затем продолжить анализ следующего нечислового символа.

4 голосов
/ 05 августа 2009

Цитирование из документации (Delphi 7) по TApplication.OnException

"Use OnException to change the default behavior that occurs when an exception is not
handled by application code."

Итак: в обработчике события OnException будет доступно только необработанное исключение . То, что вы испытываете, - это, вероятно, нарушение Delphi IDE для исключения. Это (по крайней мере, в Delphi 7) настраивается.

В Delphi 7 вы можете настроить его, щелкнув в меню Сервис-> Параметры отладчика. Затем установите флажок «Исключения языка» и снимите флажок «Остановить исключения Delphi». Однако он может отличаться в других версиях Delphi.

1 голос
/ 05 августа 2009

Application.OnException должен запускаться только для необработанных исключений. Повторное возбуждение исключения в блоке try-исключения приведет к тому, что исключение будет обработано Application.OnException. Для проверки ввода, которая вызывает исключение, вы можете отобразить сообщение пользователю, а затем повторно вызвать исключение, только если вы хотите, чтобы оно было записано в журнал ошибок.

1 голос
/ 05 августа 2009

Альтернативой может быть не использовать Application.OnException. Но просто перехватить все исключения в вашей «основной» функции. Таким образом, вы можете перехватить все исключения, которые ранее не кэшировались, зарегистрировать исключение, а затем завершить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...