Понятие механизма исключений

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

Пример. Предположим, что необходимо отобразить данные в таблице на экране и эти данные хранятся в текстовом файле. Для этого может понадобиться последовательность вложенных процедур, представленная на рис. 5.1.

I-------------------- 1---------------------- 1 I---------------------------------------

' i

Рис. 5.1. Пример вложенного вызова процедур

При этомDisplayDatalnGrid вызываетRetrieveData, которая в свою очередь вызываетOpanFile, ReadFile, CloseFile.

Если произойдет какая-либо ошибка при открытии файла, то функция

OpenFile должна вернуть соответствующую информацию в функцию

RetrieveData, которая должна содержать код, блокирующий вызовы функций

ReadFile иCloseFile, а также сообщить о произошедшем в функцию

DisplayDatalnGrid, которая не должна в этом случае пытаться выводить данные в таблицу.

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

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

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

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

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

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

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

. Ключевое словоtry указывает начало защищенного блока кода.

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

on <тиа исключительной ситуации> do <оператор>

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

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

При возникновении исключительной ситуации Delphi создает объект одного из классов исключений, определенных в системе. Все эти классы имеют общего предка - класс Exception. Иерархия классов-исключений представлена в табл. 5.1.


1а6лииа5.1
1 № Исключение Описание базового класса исключений
Excepion Базовый класс все* исключений
EAbort Исключение, не выдающее сообщения. Предназначено для намеренного прерывания вычислений и быстрого выхода из глубоко вложенных процедур и функций. Генерируется процедурой Abort.
EAbstractError Попытка вызвать абстрактный метод
EAccessViolation Ошибочный доступ к памяти; например, генерируется при попытке разыменования нулевого указателя nil, попытке доступа к адресу вне памяти, распределенной приложению
EArrayError Ошибка манипулирования с потомками класса TBaseArrav: использование ошибочного индекса элемента массива, добавление слишком большого числа элементов в массив фиксированной длины, попытка вставки элемента в отсортированный массив.
EAssertionFailed Ложное выражение, проверяемое процедурой Assert
EBitsError Ошибка доступа к массиву булевых величин TBits
ECacheError Ошибка построения кэша в кубе решений.
EComponentError Ошибка регистрации или переименования компонентов
EControlC Нажатие пользователем клавиш Ctrl+C при выполнении консольного приложения.
EConvertError Ошибка преобразования строк или объектов (например, в функциях StrToInt, StrToFloat. StrToDate)
П EDatabase Error Ошибка работы с базами данных
11.1 EDBClient Ошибка в наборе данных клиента. Свойство ErrorCode содержит код ошибки, возвращаемый ВОЕ.
11.2 EReconcileError Ошибка обновления данных компонента TClientDataset; свойство Context содержит информацию в виде сообщения об ошибке
11.3 EDBEngineError Ошибка в BDE. Свойство Errors содержит информцию об ошибке - объект типа TDBErrors. Свойство ErroiCotmt хранит число ошибок.
11.4 ENoResultSet Генерируется компонентом TQuery при попытке открыть запрос без оператора SELECT
11.5 EUpdateError Ошибка при обновлении TProvider
EDateTimeErTor Ошибка ввода даты или времени в компоненте TDateTimePicker
EDBEditError Ошибка при попытке приложения использовать данные, не соответствующие заданной маске для поля.
EDimensionMapError Ошибка формата данных в кубе решений
HDimlndexError Ошибочный индекс в задании размерности в кубе решений
E External Exception Неизвестный код исключения
ElnOutError Ошибка ввода-вывода из файла; поле errorcode содержит информацию о конкретном виде ошибки
i EInlError Базовый тип исключений целочисленных математических операций (см. директивы компилятора ($1-> и {$!+})
! 18.1 EDivByZero Попытка целочисленного деления на нуль
1 18.2 hRanRcError Целочисленное деление или индекс вне допустимого диапазона
18.3 ElntOverflow Переполнение в операции с целыми числами
EIntfCastError Ошибочное применение операции преобразования типов as к интерфейсу .....................................................................
ElnvalidCast Ошибка преобразования объекта операцией as
21 22 EInvalidGraphic ElnvalidGraphicOpe- ration Ошибочная операция с графикой
  ElnvalidGridOperation Ошибочная операция с таблицей
ElnvalidOperation Ошибочная операция с компонентом; генерируется при попытке выполнить операцию, которая требует обработчика окна, над компонентом, не имеющим родителя (Parent=nil). Это исключение также генерируется при выполнении операций перетаскивания над формой (например, Forml.BeginDrag)
  EInvalidPointer Ошибочная операция с указателем
EListError Ошибка работы с объектом типа списка TStringList и TList: а) при попытке сослаться на элемент с индексом вне допустимых пределов, б) попытке добавления дубликата строки в объект TStringList, в котором значение свойства Duplicates равно dupError, в) попытке вставить элемент в сортированный список, так как это может нарушить правильную последовательность элементов
ELowCapacityError Попытка выделить памяти больше, чем доступно кубу решений; надо или увеличить значение Capacity, или уменьшить размерность куба.
EMathError Базовый класс исключений операций с плавающей запятой; всегда генерируются только потомки этого исключения; обработка исключения EMathError может использоваться для перехвата всех исключений операций с плавающей запятой.
28.1 EInvalidArgument Недопустимое значение параметра при обращении к математической функции
28.2 EInvalidOp Неопределенная операция с плавающей запятой: процессор наталкивается на неопределенную инструкцию, ошибочную операцию или переполняется стек процессора с плавающей запятой.
28.3 EOverflow Переполнение регистра при операции с плавающей запятой
28.4 EUnderflow Потеря значащих разрядов при операции с плавающей запятой
28.5 EZeroDivide Деление на нуль числа с плавающей запятой
EMClDevice Error Ошибка доступа к устройствам мультимедиа через драйвер Media Control Interface (MCI)
EMenuError Ошибка, связанная с элементами меню
EOleCtrlError Генерируется при невозможности связать приложение с компонентом ActiveX
FOleError Низкоуровневая ошибка OLE; Delphi проверяет это исключение, но не генерирует его j
32.1 EOleSysError Ошибка OLE специфичная для интерфейса OLE IDispatch; свойство ErrorCode содержит номер ошибки
32.1.1 EOleException Ошибка OLE, связанная с методом или свойством
EOutlineError Ошибка при работе с компонентом Outline
EOutOfMemory Неудачная попытка динамически выделить память; может генерироваться процедурой OutOfMemoryError
34.1 EOutOfResources Генерируется при попытке приложения создать обработчик Windows, когда Windows не имеет места для размещения дополнительных разработчиков; возможно и при выделении других ресурсов Windows
EPackageError Исключение времени проектирования, генерируемое при загрузке или использовании пакета
EParserError Ошибка преобразования текста описания формы в двоичное представление, происходящая обычно из-за синтаксической ошибки исходного текста (часто из-за исправления текста вручную)
E Printer Ошибка печати; например, приложение пытается использовать принтер, которого нет, или задание по какой-то причине не может быть послано на принтер
EPrivelcge Попытка приложения выполнит ь инструкцию процессора, которая недоступна для текущего уровня привилегий
EPropReadOnly Попытка записать с помощью OLE значение свойства, которое предназначено только для чтения
EPropWriteOnly Попытка прочитать с помощью OLE значение свойства, которое предназначено только для записи
EPropertyError Ошибка при задании значения свойства
ERegistry Exception Ошибка при обращении к реестру
EReportError Ошибка задания типа сервера, из-за которой компонент Report не может соединиться с базой данных
EResNotFound Ошибка при загрузке файла ресурсов *.dfm и *.res в процессе проектирования
EStackOverflow Переполнение стека; размеры стека можно регулировать с помощью директивы {$М}
EStream Error Базочый класс исключений ошибок потоков
46.1 EFCreateError Ошибка создания файла (недопустимое имя файла, указанный файл уже существует и не может быть перезаписан и т.д.);
46.2 EFOpenError Ошибка открытия файла
46.3 EFilerError Базовый класс исключений файловых потоков
46.3.1 EReadError Невозможно прочесть заданное число байтов
46.3.? EWriteError Невозможно записать заданное число байтов
46.3.3 EClassNotFound Компонент не связан с приложением
46.3.4 EInvalidlmage Невозможно прочесть файл ресурсов
46.3.5 EMethodNotFound Невозможно найти реализацию метода
EStringListError Ошибочный доступ к окну списка с неверным индексом
EThread Конфликт в многопоточном приложении (например, вызов метода Synchronize объекта Thread до успешного завершения его предыдущего вызова)
ETreeViewError Ошибка вызова при работе с компонентом TreeView
EUnsupportedType- Error Ошибка выбора типа поля в качестве размерности куба решений
EVariantError Ошибка, связанная с типом данных variant
EWin32Error Ошибка Windows
         


Наши рекомендации