Главная » Delphi » Структурная обработка исключений

0

(SEH — Structured Exception Handling) представ ляет собой  метод обработки ошибок. Благодаря ему можно  восстановить нормальную работу  приложения после  сбоя  в работе программы, который в противном  случае стал бы фатальным. Исключения были  введены в язык  Object  Pascal в Delphi 1.0, но только  начиная с Delphi  2.0 они  стали  частью  интерфейса API Win32. То,  что  исклю чения являются не более  чем классами, содержащими информацию о месте  и харак тере  каждой  ошибки, делает  их применение в Object  Pascal  простым и общедоступ ным. Это позволяет реализовать и использовать исключения в приложениях наравне с любым другим классом.

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

В листинге 2.3 приведен пример обработки исключения при файловых операциях ввода/вывода.

Листинг 2.3. Обработка исключений файловых операций

Program FileIO;

uses Classes, Dialogs;

{$APPTYPE CONSOLE}

var

F: TextFile;

S: string;

begin

AssignFile(F, ‘FOO.TXT’);

try

Reset(F);

try

ReadLn(F, S);

finally

CloseFile(F);

end;

except

on EInOutError do

ShowMessage(‘Error Accessing File!’);

end;

end.

В данном  листинге внутренний блок  try..finally используется для гарантии того,  что  файл  будет  закрыт в  любом  случае,  т.е.  независимо от  того,  допущена ошибка  или  нет.  Иначе говоря, это  звучит  так: “Программа, попытайся выполнить код  между  операторами try и  finally. Независимо от  того,  возникла проблема или нет,  выполни код между операторами finally и end. Но если проблема все же возникла, обратись к блоку обработки”.

НА ЗАМЕТКУ

Операторы после ключевого слова finally в блоке try..finally выполняются не- зависимо от того, произошло исключение в процессе выполнения этого блока или нет. Создавая этот код, убедитесь, что он не зависит от того, передавалось исключение или нет. Кроме того, в связи с тем, что оператор finally не прекращает продвижения исключения, выполнение программы возобновится в расположенном далее по тексту программы блоке обработки исключения.

Внешний блок  try..except используется  для  обработки исключения, которое может  произойти в программе. После  закрытия файла  во внутреннем блоке  finally блок except выводит сообщение об ошибке  (если она произошла).

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

Безусловно, блок try..finally не сможет перехватить абсолютно все исключения. Помещая в программу блок try..finally, программист заботится не только  об обна ружении некоторого конкретного исключения. Основная цель состоит в том, чтобы выполнить все необходимые действия для корректного выхода  из любой нештатной си туации,  которая может  произойти при  выполнении этого  фрагмента программы. Блок finally является идеальным местом  для выполнения действий по освобождению лю бых распределенных ресурсов, поскольку  он выполняется всегда, включая  и случай воз никновения ошибки. Тем не менее, во многих  ситуациях обработка ошибок  может быть связана с выполнением определенных действий, зависящих от типа возникшей ошибки. Для этого  и предназначен блок обработки исключений try..except, пример исполь зования которого показан в листинге 2.4.

Листинг 2.4. Блок обработки исключений try..except

Program HandleIt;

{$APPTYPE CONSOLE}

var

R1, R2: Double;

begin

while True do begin

try

Write(‘Enter a real number: ‘);

ReadLn(R1);

Write(‘Enter another real number: ‘);

ReadLn(R2);

Writeln(‘Now divide the first number by the second…’);

Writeln(‘The answer is: ‘, (R1 / R2):5:2);

except

On EZeroDivide doWriteln(‘You cannot divide by zero!’); On EInOutError do

Writeln(‘That is not a valid number!’);

end;

end;

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

try

Statements // Вероятный источник исключений

except

On ESomeException do Something; // Обработчик конкретного

// исключения

else

{ Стандартный обработчик для всех остальных исключений }

end;CОВЕТ

При использовании конструкции try..except..else следует учитывать, что в блоке else будут обрабатываться все типы ошибок, включая и те, которых никто не ожидал, например ошибки выделения памяти или некоторые типы ошибок выполнения про- граммы. Поэтому при использовании ключевого слова else проявляйте осторожность, ведь в случае некорректной обработки исключения возникает еще одно исключение. Более подробная информация по этой теме приведена в настоящей главе далее.

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

try

Statements // Вероятный источник исключений

except

HandleException // Аналог оператора else end;

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии