Как поймать исключения в разделе инициализации модулей в Delphi

У меня есть сторонний модуль, ведьма вызывает исключение в разделе инициализации модуля. Как я могу поймать это исключение в своем приложении?


person Reza    schedule 06.06.2014    source источник
comment
У Дэвида, вероятно, есть ответ :) Я предполагаю, что вы можете что-то подключить, добавив свой модуль перехвата до того, как сторонний модуль в списке использует список. Это должно быть возможно, потому что такие библиотеки, как MadExcept и EurekaLog, подключаются к исключениям.   -  person Graymatter    schedule 06.06.2014


Ответы (2)


Вы не можете поймать такую ​​вещь. RTL выполняет разделы инициализации, и правила заключаются в том, что никакие исключения не должны вызываться. Если возникают исключения, то ошибка является терминальной.

Другой способ решить эту проблему заключается в том, что когда секции инициализации начинают выполняться, структура обработки исключений языка еще не установлена. Это само устанавливается как часть инициализации RTL.

Решение состоит в том, чтобы исправить код, чтобы он подчинялся правилам. В разделах инициализации исключений не возникает.


Что ж, я полагаю, что вы могли бы перехватить код RTL, который выполняет инициализацию, и, возможно, заменить этот код RTL устойчивым к исключениям кодом. Но какой в ​​этом смысл? Если раздел инициализации вызывает исключение, единственное разумное предположение, которое следует сделать, состоит в том, что модуль не инициализирован и, следовательно, не пригоден для использования. Пожалуйста, не пытайтесь зарыть голову в песок и игнорировать настоящую проблему. Исправьте сторонний код.

person David Heffernan    schedule 06.06.2014
comment
@RezaRahmati Я не думал об этой последней части, но это действительно важно. В тот момент, когда вы игнорируете исключение, вы не можете гарантировать, что какой-либо код, выполняемый вашим приложением, использующим эту библиотеку, будет работать должным образом. Такие вещи имеют привычку забываться и очень сильно кусаться в конце концов, когда вы меньше всего этого ожидаете. - person Graymatter; 06.06.2014
comment
Вы не можете поймать такую ​​вещь. - может правильнее не ловить такие вещи, но в целом я согласен с Дэвидом. Примечание от docwiki.embarcadero: Вызов исключения в разделе инициализации модуля может не привести к ожидаемому результату. Обычная поддержка исключений обеспечивается модулем SysUtils, который необходимо инициализировать, прежде чем такая поддержка станет доступной. Если во время инициализации возникает исключение, все инициализированные модули, включая SysUtils, завершаются, а исключение вызывается повторно. Затем исключение перехватывается и обрабатывается, обычно путем прерывания программы. - person Andrei Galatyn; 06.06.2014
comment
Вы даже не можете (только что попробовали) подключиться к Application.OnException в одном из ваших собственных UNIT (который должен быть загружен перед UNIT, вызывающим исключение) - вероятно, потому, что все инициализированные модули, включая SysUtils, завершены, а исключение повторно -raised.. Обработчик Application.OnException никогда не вызывается. Получается, что без серьезного взлома тут не обойтись. При этом я согласен с другими описанными здесь настроениями - такое исключение (при инициализации UNIT) всегда должно приводить к завершению процесса, поскольку результирующее состояние программы не определено... - person HeartWare; 06.06.2014
comment
@HeartWare Вы можете сделать это, только если подключите InitUnits к System. Кодовый хук сделает свою работу. Не хорошая идея ум. - person David Heffernan; 06.06.2014
comment
@AndreiGalatyn Без взлома не поймаешь. Спрашивающий хочет перехватить исключение за пределами стороннего модуля. - person David Heffernan; 06.06.2014
comment
@David Я полагал, что должен быть какой-то стандартный способ его поймать (ApplicationHandleException или что-то подобное), но, похоже, вы правы, все эти стандартные методы нельзя использовать в этом случае. - person Andrei Galatyn; 06.06.2014
comment
Спасибо за ответ, третья сторона, которую я использую, просто блокирует код страны, и если я добавлю это устройство, приложение будет закрыто в этих странах, я просто хочу избавиться от него. Любое решение? - person Reza; 06.06.2014
comment
Исправьте код этой сторонней библиотеки, чтобы она не вызывала исключений в коде инициализации. - person David Heffernan; 06.06.2014
comment
Вы можете поймать это, заменив RaiseExceptionProc в разделе инициализации модуля, который размещен перед сторонним модулем. Я понятия не имею, принесет ли это пользу, хотя.. - person Sertac Akyuz; 06.06.2014

Вы можете попробовать OnExceptionEvent класса TApplicationEvents, но я не уверен, что это работает.

person user3684240    schedule 07.06.2014
comment
Пожалуйста, обратитесь к документации, если вы не уверены: OnException обрабатывает только те исключения, которые возникают во время обработки сообщения.. - person Sertac Akyuz; 07.06.2014