Изучение Delphi

Delphi обработка исключений – exception-handling — Delphi — Обработка исключений на его собственном конструкторе после того, как он поднят

Класс Exception — обработка исключений


Класс Exception является прямым потомком базового класса TObject. Вместе со своими потомками он предназначен для обработки исключительных ситуаций (исключений), возникающих при некорректных действиях программы: например в случае деления на ноль, при попытке открыть несуществующий файл, при выходе за пределы выделенной области динамической памяти и т. п. В этом разделе рассматриваются основные свойства исключений и их использование для повышения надежности программ.

При работе в среде Delphi эксперименты с исключениями плохо прослеживаются, так как при каждом исключении среда перехватывает управление программой. В этом случае бывает полезно отменить такое поведение среды. Для этого выберите в меню команду Tools ► Debugger Options и на вкладке Language Exceptions открывшегося окна сбросьте флажок Stop on Delphi Exceptions, а в предыдущих версиях Delphi (5 и ниже) выберите команду Tools ► Environment Options и на вкладке Preference сбросьте флажок Break on exception.

Для обработки исключений в Delphi предусмотрен механизм защищенного блока. Защищенный блок начинается зарезервированным словом try (попытаться [выполнить]) и завершается словом end. Как показано далее, существуют два

СОВЕТ

4.1.1. Защищенные блоки типа защищенных блоков — except (исключить) и finally (в завершение), отличающихся способом обработки исключения:

try try

<операторы> <операторы> except finally

<обработчики исключений> <операторы> else end;

<операторы> end;

В блоке except порядок выполнения операторов таков: сначала выполняются операторы секции try…except; если операторы выполнены без возникновения исключительной ситуации, работа защищенного блока на этом прекращается и управление получает оператор, следующий за словом end; если при выполнении части try возникло исключение, управление получает соответствующий обработчик в секции except, а если таковой не найден — первый из операторов, следующих за словом else. В блоке finally операторы в секции f inally…end получают управление всегда, независимо от того, возникло исключение в секции try…f inally или нет. Если исключение возникло, все операторы в секции try…f inally, следующие за «виновником» исключения, пропускаются, и управление получает первый оператор секции f inally…end. Если исключения не было, этот оператор получает управление после выполнения последнего оператора секции try…f inally.

Обработчики исключений в блоке except имеют такой синтаксис:

on <класс исключения> do <оператор>;

Здесь on, do — зарезервированные слова; <класс исключения> — класс обработки исключения; <оператор> — любой оператор Delphi, кроме оператора передачи управления goto на метку, расположенную вне блока except.

Обратите внимание: имя класса служит своеобразным ключом выбора, а собственно обработка осуществляется оператором, следующим за do (этот оператор может быть составным, так что обработка исключения может занимать произвольное количество операторов Delphi).

Поиск нужного обработчика осуществляется с начала списка вниз до тех пор, пока не встретится класс, способный обрабатывать исключение данного типа. Если подходящего класса не обнаружено, управление передается операторам, следующим за словом else, а если таковых нет (часть else <операторы> может опускаться), выполняется умалчиваемая обработка исключения.

Если для программиста важен лишь сам факт возникновения исключения и несущественен тип связанной с ним ошибки, он может опустить в секции except…end обработчики вместе со словом else, оставив в ней лишь необходимый код реакции на любую ошибку:

try

except

ShowMessage(‘Ошибка!1) ; end;

Защищенные блоки могут вкладываться друг в друга на неограниченную глубину, так как везде, где в предыдущих описаниях использовалась запись <олераторы> или <оператор>, могут присутствовать любые операторы Delphi, в том числе try…except или try…f inally:

try try

finally

end; except

on EMatchError do begin

try

try

end;

end;

end;

end;

⇐Классы общего назначения || Оглавление || 4.1.2. Класс Exception⇒

www.delphiplus.org

Структурная обработка исключительных ситуаций- Статьи по delphi

Структурная обработка исключительных ситуаций

Структурная обработка исключительных ситуаций — это система, позволяющая программисту при возникновении ошибки (исключительной ситуации) связаться с кодом программы, подготовленным для обработки такой ошибки. Это выполняется с помощью языковых конструкций, которые как бы «охраняют» фрагмент кода программы и определяют обработчики ошибок, которые будут вызываться, если что-то пойдет не так в «охраняемом» участке кода. 

При традиционной обработке ошибок, ошибки, обнаруженные в процедуре обычно передаются наружу (в вызывавшую процедуру) в виде возвращаемого значения функции, параметров или глобальных переменных (флажков). Каждая вызывающая процедура должна проверять результат вызова на наличие ошибки и выполнять соответствующие действия. Часто, это просто выход еще выше, в более верхнюю вызывающую процедуру и т.д. : функция A вызывает B, B вызывает C, C обнаруживает ошибку и возвращает код ошибки в B, B проверяет возвращаемый код, видит, что возникла ошибка и возвращает код ошибки в A, A проверяет возвращаемый код и выдает сообщение об ошибке либо решает сделать что-нибудь еще, раз первая попытка не удалась.

Традиционная обработка ошибок

При традиционной обработке ошибок, ошибки, обнаруженные в процедуре обычно передаются наружу (в вызывавшую процедуру) в виде возвращаемого значения функции, параметров или глобальных переменных (флажков). Каждая вызывающая процедура должна проверять результат вызова на наличие ошибки и выполнять соответствующие действия. Часто, это просто выход еще выше, в более верхнюю вызывающую процедуру и т.д. : функция A вызывает B, B вызывает C, C обнаруживает ошибку и возвращает код ошибки в B, B проверяет возвращаемый код, видит, что возникла ошибка и возвращает код ошибки в A, A проверяет возвращаемый код и выдает сообщение об ошибке либо решает сделать что-нибудь еще, раз первая попытка не удалась.

Такая «пожарная бригада» для обработки ошибок трудоемка, требует написания большого количества кода в котором можно легко ошибиться и который трудно отлаживать. 

Одна ошибка в коде программы или переприсвоение в цепочке возвращаемых значений может привести к тому, что нельзя будет связать ошибочное состояние с обработчиком ошибки. Результатом будет ненормальное поведение программы, потеря данных или ресурсов, или крах системы.

Структурная обработка ошибок

Структурная обработка исключительной ситуации замещает ручную обработку ошибок автоматической, сгенерированной компилятором системой уведомления. В приведенном выше примере, процедура A установила бы «охрану» со связанным обработчиком ошибки на фрагмент кода, в котором вызывается B. B просто вызывает C. Когда C обнаруживает ошибку, то создает (raise) исключительную ситуацию. Специальный код, сгенерированный компилятором и встроенный в Run-Time Library (RTL) начинает поиск обработчика данной исключительной ситуации. При поиске «защищенного» участка кода используется информация, сохраненная в стеке. В процедурах C и B нет такого участка, а в A — есть. Если один из обработчиков ошибок, которые используются в A, подходит по типу для возникшей в C исключительной ситуации, то программа переходит на его выполнение. При этом, область стека, используемая в B и C, очищается; выполнение этих процедур прекращается.

Если в A нет подходящего обработчика, то поиск продолжается в более верхнем уровне, и так может идти, пока поиск не достигнет подходящего обработчика ошибок среди используемых по умолчанию обработчиков в RTL. Обработчики ошибок из RTL только показывают сообщение об ошибке и форсированно прекращают выполнение программы. Любая исключительная ситуация, которая осталась необработанной, приведет к прекращению выполнения приложения. 

Без проверки возвращаемого кода после каждого вызова подпрограммы, код программы должен быть более простым, а скомпилированный код — более быстрым. При наличии исключительных ситуаций подпрограмма B не должна содержать дополнительный код для проверки возвращаемого результата и передачи его в A. B ничего не должна делать для передачи исключительной ситуации, возникшей в C, в процедуру A — встроенная система обработки исключительных ситуаций делает всю работу. 

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

Модель исключительных ситуаций в Delphi

Модель исключительных ситуаций в языке Delphi является невозобновляемой (non-resumable). При возникновении исключительной ситуации Вы уже не сможете вернуться в точку, где она возникла, для продолжения выполнения программы (это позволяет сделать возобновляемая (resumable) модель). 

Невозобновляемые исключительные ситуации разрушают стек, поскольку они сканируют его в поисках обработчика.

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

В язык Object Pascal было добавлено ключевое слово try. Оно используется для обозначения первой части защищенного участка кода. Существует два типа защищенных участков:

Первый тип используется для обработки исключительных ситуаций. 

Для уверенности в том, что ресурсы, занятые вашим приложением, освободятся в любом случае, Вы можете использовать конструкцию второго типа. Код, расположенный в части finally, выполняется в любом случае, даже если возникает исключительная ситуация. 

При вызове исключительной ситуации (raise) автоматически создается экземпляр соответствующего класса, который и содержит информацию об ошибке. Обработчик может получить доступ к этому объекту используя следующий синтаксис:

Пример демонстрирует еще одно новшество в языке Object Pascal — создание локальной переменной. В примере локальной переменной является E — это экземпляр класса ESampleError, который был создан в процедуре C в момент вызова исключительного состояния. Переменная E доступна только внутри блока do. Свойство Message объекта E содержит сообщение, которое было передано в конструктор Create в процедуре C. 

Еще один способ доступа к объекту исключительной ситуации  — использовать функцию ExceptionObject

delphiexample.at.ua

Обработка исключительных ситуаций в Delphi. Восприятие ввода от пользователя

ЛАБОРАТОРНАЯ РАБОТА № 1

 

                                    Обработка исключительных ситуаций в Delphi. Восприятие ввода от пользователя

 

1. Цель работы

 

Ознакомление с классом  исключительных ситуаций Delphi и создание приложений, генерирующих исключения и обрабатывающие различные фокусы ввода.

 

2. Домашнее задание

 

Изучить разделы 5 и 6 конспекта лекций, ознакомиться с описанием

 

    • заданием на лабораторную работу.

 

 

  1. Основные понятия и приемы

 

3.1. Обработка исключений

 

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

 

Весь механизм строится на четырех  ключевых словах:

 try – определяет начало защищенного блока кода;

except – определяет конец защищенного блока кода и вводит операторы обработки исключений в следующем виде:

 

on (тип исключения) do (оператор)

finally – указывает необязательный блок, который используется для освобождения ресурсов, распределенных в блоке try перед обработкой исключения; этот блок завершается ключевым словом end.

raise – оператор, используемый для порождения исключений. Большинство исключений, которые вы встретите при программировании на Del-phi, будут порождаться системой, но вы также можете создать их в собственном коде, когда во время выполнения обнаружатся недопустимые или несогласованные данные. Кроме того, ключевое слово raise можно использовать внутри обработчика для повторного порождения исключе

ния, т.е. для передачи его следующему обработчику.

 

Если вы хотите, чтобы при правильной обработке исключений программа продолжала выполняться, отключите опцию отладки Break on Exception в

 

окне Environment Options.

 

3.2. Предопределенные обработчики  исключительных ситуаций

 

Ниже Вы найдете справочную информацию по предопределенным исключениям, необходимую для профессионального программирования в

Delphi.

 

  • Exception — базовый класс-предок всех обработчиков исключительных ситуаций.
  • EAbort — “скрытое” исключение. Используйте его тогда, когда хотите прервать тот или иной процесс с условием, что пользователь про-граммы не должен видеть сообщения об ошибке. Для повышения удобства использования в модуле SysUtils предусмотрена процедура

 

Abort, определенная как: procedure Abort; begin

 

raise EAbort.CreateRes(SOperationAborted) at ReturnAddr; end;

 

  • EComponentError — вызывается в двух ситуациях:

 

    1. при попытке регистрации компоненты за пределами процедуры Register;
    2. когда имя компоненты не уникально или не допустимо.

 

  • EConvertError — происходит в случае возникновения ошибки при выполнении функций StrToInt и StrToFloat, когда конвертация строки в соответствующий числовой тип невозможна.

 

  • EInOutError — происходит при ошибках ввода/вывода при включенной директиве {$I+}.

 

  • EIntError — предок исключений, случающихся при выполнении целочисленных операций.
  • EDivByZero  —  вызывается в случае деления на ноль,  как результат

 

RunTime Error 200.

 

  • EIntOverflow — вызывается при попытке выполнения операций, при-водящих к переполнению целых переменных, как результат RunTime Error 215 при включенной директиве {$Q+}.
  • ERangeError — вызывается при попытке обращения к элементам массива по индексу, выходящему за пределы массива, как результат RunTime Error 201 при включенной директиве {$R+}.

 

  • EInvalidCast — происходит при попытке приведения переменных одного класса к другому классу, не совместимому с первым (например, приведение переменной типа TListBox к TMemo).

 

  • EInvalidGraphic — вызывается при попытке передачи в LoadFromFile файла, несовместимого графического формата.

 

  • EInvalidGraphicOperation — вызывается при попытке выполнения операций, неприменимых для данного графического формата (например, Resize для TIcon).

 

  • EListError — вызывается при обращении к элементу наследника TList по индексу, выходящему за пределы допустимых значений (например, объект TStringList содержит только 10 строк, а происходит обращение к одиннадцатому).

 

  • EMathError — предок исключений, случающихся при выполнении операций с плавающей точкой.

 

  • EOverflow — происходит как результат переполнения операций с плавающей точкой при слишком больших величинах. Соответствует

RunTime Error 205.

 

  • Underflow — происходит как результат переполнения операций с плавающей точкой при слишком малых величинах. Соответствует

 

RunTime Error 206.

 

  • EZeroDivide — вызывается в результате деления на ноль.
  • EMenuError — вызывается в случае любых ошибок при работе с пунктами меню для компонент TMenu, TMenuItem, TPopupMenu и их наследников.
  • EOutlineError — вызывается в случае любых ошибок при работе с TOutLine и любыми его наследниками.
  • EOutOfMemory — происходит в случае вызовов New(), GetMem() или конструкторов классов при невозможности распределения памяти.

 

Соответствует RunTime Error 203.

 

  • EPrinter — вызывается в случае любых ошибок при работе с принтером.
  • EProcessorException — предок исключений, вызываемых в случае прерывания процессора- hardware breakpoint. Никогда не включается в DLL, может обрабатываться только в “цельном” приложении.

 

  • EBreakpoint — вызывается в случае останова на точке прерывания при отладке в IDE Delphi. Среда Delphi обрабатывает это исключение самостоятельно.
  • EFault — предок исключений, вызываемых в случае невозможности обработки процессором тех или иных операций.
  • EInvalidOpCode — вызывается, когда процессор пытается выполнить недопустимые инструкции.
  • ESingleStep  —  аналогично EBreakpoint,  это исключение происходит

 

18при пошаговом выполнении приложения в IDE Delphi.

 

  • EPropertyError — вызывается в случае ошибок в редакторах свойств, встраиваемых в IDE Delphi. Имеет большое значение для написания надежных property editors. Определен в модуле DsgnIntf.pas.

 

  • EResNotFound — происходит в случае тех или иных проблем, имеющих место при попытке загрузки ресурсов форм — файлов .DFM в режиме дизайнера. Часто причиной таких исключений бывает нарушение соответствия между определением класса формы и ее описанием на уровне ресурса (например, вследствие изменения порядка следования полей-ссылок на компоненты, вставленные в форму в режиме дизайнера).

 

  • EStreamError — предок исключений, вызываемых при работе с потоками.

 

  • EFCreateError — происходит в случае ошибок создания потока (например, при некорректном задании файла потока).
  • EFilerError — вызывается при попытке вторичной регистрации уже зарегистрированного класса (компоненты). Является, также, предком специализированных обработчиков исключений, возникающих при работе с классами компонент.

 

3.3. Восприятие ввода  от пользователя

 

Обратим особое внимание на одно качество, характерное для многих управляющих элементов – фокус. Как определить какое окно или поле имеет фокус ввода? В каждый конкретный момент фокус имеет только одно поле. Вы можете перемещать фокус, используя клавишу Tab или щелкая мы-шью по другому компоненту. Каждый раз когда компонент получает или теряет фокус, к нему приходит соответствующее событие, которое указывает, что пользователь достиг (OnEnter) или покинул (OnExit) компонент.

 

При использовании компонента Edit для ввода чисел пользователь вместо цифры может набрать букву. Функции преобразования вернут код ошибки, что поможет определить действительно ли введено число. Когда можно выполнить такую проверку? Возможно, когда изменится значение блока редактирования, когда компонент потеряет фокус или когда пользователь щелкнет по некоторой кнопке в диалоговой панели. Можно просматривать входной поток в блоке редактирования и останавливать любой нечисловой код.

 

 

4. Порядок выполнения работы

 

  1. В среде программирования Delphi cоздайте новый проект, выбрав пункт меню File/New Application.

 

19Сохраните этот проект в папке»С:\Ваша_группа\Ваша_фамилия Lab2″. (Unit1.pas под новым именем Main2.pas, а Project1.dpr под новым именем Lab2.dpr).

 

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

 

  1. Открыть новое приложение.
  2. Создать форму с пятью полями редактирования и пятью соответствующими надписями, которые поясняют, какой вид проверки осуществляет

соответствующий компонент Edit. Форма также содержит кнопку для проверки содержимого первого поля редактирования.

 

Событие OnClick кнопки должно проверять целочисленность введенного в первое поле значения, например:

var

Number, Code : Integer ; begin

 

if Edit1.Text <> ‘ ’ then begin

 

val ( Edit1. Text, Number, Code) ; if Code <> 0 then

begin

 

Edit1. SetFocus ;

MessageDlg (‘ Not a number in the first edit ‘ , mtError, [ mbOK ] , 0 ) ;

 

end ; end ;

end ;

♦ При выходе из компонента Edit2 (событие OnExit) осуществляется аналогичная проверка.

 

var

Number, Code : Integer ; begin

 

if (Sender as TEdit ). Text <> ‘ ’ then begin

 

val ((Sender as TEdit ). Text, Number, Code) ; if Code <> 0 then

begin

 

(Sender as TEdit ). SetFocus ; MessageDlg (‘ The edit field number ‘ +

IntToStr ((Sender as TEdit ). Tag) +

 

‘ does not have a      valid number’ , mtError, [ mbOK ] , 0 ) ;

end ; end ;

 

end ;

 

Текст сообщения об ошибке может  варьироваться.

 

♦ Третий компонент Edit выполняет аналогичную проверку при каждом изменении его содержимого (используя событие OnChange}.

♦ Записать код для события события OnKeyPress компонента Edit4 и про-верить, не является ли введенный символ числом или клавишей Back-space (которая имеет числовое значение 8).

 

begin

if not ( key in [ ‘0’ . . ‘9’ , # 8] } then begin

 

Key  := # 0 ;

MessageBeep ($ FFFFFFFF) ; end;

 

end;

 

♦ Для события OnEnter компонента Edit5 записать код, в котором необходимо преобразовать введенные символы в число с помощью функции StrToInt. Использовать исключение для обработки ошибки EConvertError.

 

    1. Варианты индивидуальных заданий

 

      1. Создать программу, позволяющую пользователю ввести два числа, которые программа разделит. Необходимо поместить на форму три объекта класса TEdit — два для операндов, один – для результата и кнопку (объект класса TButton), нажимая на которую пользователь выполняет деление. Исключить попытку деления на ноль а так же введения символов вместо цифр. Выдать сообщение о типе возник-шей ошибке.

 

      1. Создать программу, вычисляющую корни квадратного уравнения (ax2+bx+c=0). Необходимо поместить на форму четыре объекта класса TEdit — три для коэффициентов квадратного уравнения, один – для результата и кнопку (объект класса TButton), нажимая на кото-рую пользователь выполняет нахождение корней. Исключить ввод символов вместо цифр, получение отрицательного дискриминанта и ввод а = 0. Вывести при всех типах ошибок одно и то же сообщение.

stud24.ru

multithreading — Обработка исключений Delphi, используйте E: Exception или ExceptObject

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

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

Но ответить на то, что, я думаю, вы спросили. Исключение класс не является потокобезопасным. И ваши коллеги были неправы, поскольку никто не принуждался использовать определенную обработку исключений в потоках. Эти правила одинаковы для всех потоков, созданных процессом, независимо от того, что. Просто эти объекты исключений могут быть неустойчивыми в блоках исключений:

1. Получить текущий объект исключения из ExceptObject

ExceptObject возвращает текущий объект исключения. На практике это может привести к этому; если вы храните такую ​​ссылку на объект в переменной внутри блока обработчика исключений, и в этом блоке будет поднято другое исключение, которое может привести к тому, что сохраненный экземпляр может стать недействительным. Что совершенно небезопасно.

Но это не значит, что вы не могли взять ссылку на такой объект и передать его другому потоку, используя некоторые механизмы синхронизации (так как это не потокобезопасный класс) и работать с ним там. Вам просто нужно позаботиться о том, чтобы никакое другое исключение не было вызвано, поскольку это приведет к аннулированию ранее сохраненного объекта, так как вы должны позаботиться о том, чтобы оставаться внутри обработчика исключений с точки зрения вызывающего, и вы должны использовать механизм синхронизации потоков.

Таким образом, фактически работа с объектом исключения, полученным из выражения on, может быть более стабильной, чем использование ExceptObject. Но здесь действуют те же правила; вам нужно будет синхронизировать экземпляр объекта с выражением on с другим потоком (так как он не является потокобезопасным классом), но в этом случае объект, полученный из на выражение не будет изменено в отличие от ExceptObject, которое может находиться в определенном блоке исключений.

2. Сохранять объект исключения с помощью метода AcquireExceptionObject

Функция AcquireExceptionObject позволяет сохранить объект исключения даже вне блока исключений.

Для обработки исключений, говоря о синхронизации потоков, я предлагаю вам использовать функцию AcquireExceptionObject, которая делает исключающий объект, свободный для потребления, даже после завершения блока исключений. Для вас, который несет единственную ответственность, освободите такой приобретенный объект, вызвав процедуру ReleaseExceptionObject или создав исключение этим объектом еще раз.

qaru.site

delphi — Обработка исключений в Delphi Datasnap REST Server

Tl; Dr: он не реализован применимым образом (в 10.1 Berlin).

Я столкнулся с той же проблемой, и после прочтения большого количества источников я не нашел практического решения.

Итак, примерный (мой) StackTrace будет выглядеть так:

MyClass::MyServerMethod()
/* skipping some funny unimportant RTTI/TValue handling here */
System::Rtti::TRttiMethod::Invoke
Dsreflect::TDSMethod::Invoke(TObject, TDSMethodValues)
TDSServerConnectionHandler::DbxExecute(const TDBXExecuteMessage)
TDSServerCommand::DerivedExecuteUpdate
TExecuteCallback
TDSService::Execute(const string, const TRequestCommandHandler, TExecuteCallback)
TDSService::ProcessRequest(const string, const TRequestCommandHandler, TExecuteCallback)
TDSRESTService::ProcessREST(const string, const string, const TArray<Byte>, const TRequestCommandHandler)
TDSRESTService::ProcessGETRequest(const string, TStrings, TArray<Byte>, TRequestCommandHandler)
TDSRESTServer::DoDSRESTCommand(TDSHTTPRequest, TDSHTTPResponse, string)
TDSRESTServer::DoCommand(TDSHTTPContext, TDSHTTPRequest, TDSHTTPResponse)
Dshttpwebbroker::TDSRESTWebDispatcher::DispatchRequest(TObject, Web::Httpapp::TWebRequest, Web::Httpapp::TWebResponse)

Примечание. Это полностью зависит от использования DataSnap. В вышеуказанных случаях запросы передаются в API DataSnap через TDSRESTWebDispatcher (начиная с TIdCustomHTTPServer).

  • Каждый Exception, поднятый в ServerMethod, попадет в TDSService::ProcessRequest.
  • В этой процедуре каждый Exception пойман, и ТОЛЬКО его Message добавляется к TRequestCommandHandler->CommandList.
  • Далее вниз Message записывается как команда JSON/DBX на выход.

Поэтому мы никогда не сможем обрабатывать объект Exception и обращаться к StackTrace или другой информации. Таким образом, это само по себе неприемлемо и должно изменить

Хорошей новостью является то, что эта процедура virtual и может быть перезаписана. Плохая новость заключается в том, что в приведенном выше примере вам нужно расширить TDSRESTService с помощью вашей собственной процедуры ProcessRequest (включая ваш обработчик ошибок), TDSRESTServer с собственным DoDSRESTCommand (там TDSRESTService создается в чудовищно большая процедура) и TDSRESTWebDispatcher (в зависимости от вашего использования).

Моя личная рекомендация — не использовать DataSnap.

Примечание. В момент написания этого вопроса я не нашел никакого вызова события OnError.

qaru.site

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *