Обработка исключительных ситуаций
www.delphi.agava.ru
Как возникают исключительные ситуации?
Существует множество
источников исключительных ситуаций.
Например, программой могут быть
сгенерированны исключения из-за какого-то
ненормального состояния. Исключения
генерируются компонентами Delphi для
различных событий, таких как присвоение
свойству значения, выходящего за
допустимые пределы, или попытка
индексировать несуществующий элемент
массива.
Исключительная ситуация
возникает при выполнении некорректной
математической операции, такой как деление
на ноль. Потенциально любой оператор
программы может стать причиной
исключительной ситуации. Однако некоторые
операторы относительно безопасны, и ваша
задача при написании устойчивой программы
состоит в основном в том, чтобы правильно
решить, для каких операторов нужна защита, а
какие безопасны.
Вот некоторые типы
операций, которые могут привести к
исключительным ситуациям:
обработка файла;
выделение памяти;
работа с ресурсами
системы;
работа с объектами и
формами, создаваемыми во время
выполнения программы;
аппаратные конфликты и
конфликты операционных систем.
Ключевые слова,
используемые для обработки исключительных
ситуаций.
В Object Pascal есть
несколько ключевых слов для создания и
обработки исключений. Это try, except, on-do-else,
finally, raise и at.
Блоки защищенных
опереаторов |
Блок защищенных
операторов - основное средство для
обработки исключительных ситуация. Ниже
показана схема создания блока защищенных
операторов с помощью блоков try и except.
Обратите внимание, что конструкция
заканчивается ключевым словом end;
try
{операторы, которые могут вызвать
ошибку(сгенерировать исключение)}
except
{опереаторы для обработки
сгенерированных исключений}
end;
Этот пример демонстрирует
возникновение исключительной ситуации
при делении на ноль.
procedure TForm1.Button1Click(Sender: TObject);
Var
I, J, K: integer;
begin
I:=0;
J:=10;
try
K := J div I;
showmessage(inttostr(k));
except
Showmessage ('Ошибка! Деление на ноль.');
end;
end;
|
|
! |
Внимание! При
тестировании исключительных ситуаций
желательно отключить утилиту
отслеживания сообщений WinSight32, если она
запущена. Также, если вы используете Delphi
4, выберите команду Tools => Debugger Options и на
вкладке Language Exception снимите флажок Stop on
Delphi Exception.
Теперь исключения не будут
отлавливаться средой Delphi и управление
исключительными ситуациями полностью
предается вашему приложения. |
После возникновения исключительной
ситуации в блоке try выполнение
немедленно переходит к первому оператору
блока except. После генерирования
исключительной ситуации дальнейшие
операторы блока try не выполняются.
После обработки исключительной
ситуации в блоке except продолжается
нормальное выполнение операторов
процедуры или функции, размещенных
после защищенного блока.
Блоки защищенных ресурсов |
Вывод сообщений об ошибке - это только
один аспект обработки исключительных
ситуаций. Устойчивое приложение должно
восстанавливать стабильное состояние
системы при возникновении аварийных
ситуаций. Для создания блоков защищенных
ресурсов используют блоки try и finally.
Схема создания блока защищенных
ресурсов:
try
{операторы, которые могут вызвать
ошибку(сгенерировать исключение)}
finally
{освободить ресурс; гарантированно
будет выполнено}
end;
{продолжить, если в блоке try не
возникло исключительных ситуаций}
Операторы блока finally выполняются
всегда, независимо от того, генерируется
ли в блоке try исключение. Обычно
операторы блока finally служат для
освобождения памяти, закрытия файлов и
выполнения других необходимых операций
для восстановления стабильности системы
при возникновении исключительной
ситуации.
Пример использования блока защищенных
ресурсов:
procedure TForm1.Button1Click(Sender: TObject);
Var
I, J, K: integer;
P : Pointer;
begin
I:=0;
J:=10;
getMem(P, 4098); // Выделение
памяти
try
K := J div I;
showmessage(inttostr(k));
finally
FreeMem(p, 4098); //Гарантированно
выполняется
Showmessage ('Память
освобождена');
end;
end;
|
В данном случае память
освободится в любом случае. Независимо
от исключительных ситуаций (В данном
случае - деление на ноль) |
В блоке finally не обрабатываются
исключительные ситуации - они могут быть
обработаны только в блоке except.
Операторы блока finally гарантированно
выполняются независимо от того, что
произошло в предыдущем блоке try.
Вложенные блоки try-except и try-finally |
Схема создания смешанных блоков
защищенных операторов и защищенных
ресурсов:
{Выделение ресурса}
try
try
{операторы, которые могут вызвать
ошибку(сгенерировать исключение)}
except
{Операторы
обработки исключений}
end;
finally
{Освобождение реурса}
end;
Обработка определенных
исключений |
Пример:
try
{операция печати}
finally
on E: Eprinter do
Showmessage(E.Message); //Вывести
сообщение об ошибке
end;
В данном случае отлавливается именно
ошибка при печати (EPrinter).
Классы исключений:
Eabort - исключение генерируется при вызове
процедуры аборт
EAccessViolation - Ошибка доступа
EArrayError - ошибка при работе с массивом
EBitsError - некорректная операция с
логическими массивами
EConvertError - при ошибках преобразования
типов данных
EDivByZerro - деление на ноль
EFCreateError. Указывает на ошибку при
создании файла.
EFileError. Указывает на ошибку в операциях с
файловым потоком.
EFopenError. Указывает на ошибку открытия
файла.
EInOutError. Ошибка файлового ввода-вывода. В
поле ErrorCode экземпляра исключения
содержится код ошибки ввода-вывода. Эта
исключительная ситуация может
возникнуть, только если программа
скомпилирована с директивой {$I} (она
используется по умолчанию). Коды ошибок
следующие : 2 - файл не найден, 3 - неверное
имя файла, 4 - слишком много открытых
файлов, 5 - доступ запрещен, 100 - конец файла,
101 - диск переполнен и 106 - некорректный
ввод. Так же допустимы другие коды ошибок.
EIntError. Основной класс для математических
ошибок при операциях с целыми числами.
Обьекты этого класса исключений никогда
не создаются, однако класс можно
использовать для перехвата всех ошибок в
целочисленных операциях. Для создания
обьектов исключений используйте
производные классы, такие как
EDivByZero,ERangeError и EIntOverflow.
EIntfCastError. Генерируется при попытке
некорректного приведения типов с
использованием оператора as .
EIntOverflow. Переполнение для переменной
типа Integer.
EInvalidArgument. Выходящие за допустимые рамки
значение в специализированных
математических и финансовых функциях из
модуля Math.
EInvalidCast. Неверное выражение приведения
типов.
EInvalid Graphic. Генерируется программой при
попытке открытия нераспознаваемого
графического файла (например, открытие по
ошибке текстового файла вместо файла
точечного изображения .bmp).
EInvalidGraphicOperation. Указывает на некорректную
графическую операцию, такую как попутка
изменить размер пиктограммы.
EInvalidGridOperation. Генерируется при
некорректных операциях с компонентами grid,
например при попытке обращения к
несуществующей ячейке.
EInvalidOp. Указывает на некорректную
операцию с плавающей запятой.
Генерируется при неопределенных
математических ошибках, например когда
для прцессора передается
неопределенная инструкция,
производится попытка выполнить
некорректную операцию или переполняется
стек процессора.
EInvalidOperation. Указывает на некорректную
операцию над компонентом, в частности на
операцию, требующую дескриптора окна для
компонента с неопределенным свойством
Parent. Также может быть сгенерирован при
некорректных операциях перетаскивания.
EInvalidPointer. Генерируется при
использовании неверного указателя.
Например, при попытке обращения к
указателю nil или передаче выделенного
блока памяти более одгого раза.
EMathError. Базовый класс для математических
ошибок при работе с числами с плавающей
точкой. Никогда не используется напрямую
как обьект исключения. Используются
производные классы исключений
EInvalidArgument,EInvalidOp,EOverflow,EUnderflow и EZeroDivide.
EMCIDeviceError. Указываетна ошибку при работе
с драйвером MCI(Media Control Interface).
EMenuError. Указывает на некорректную
операцию с меню. Может быть сгенерирован,
например ,при некорректном обращении к
обьекту меню.
ENoResultSet. Генерируется обьектом TQuery, если
в запросе отсутствует оператор SELECT.
EOleCtrlError. Указывает на неудачную попытку
установления связи с элементом
управления ActiveX.
EOleException. Генерируется, если вызов метода
IDispatch привел к ошибке.
EOleSysError. Генерируется при неудачном
вызове метода IDispatch.
EOutOfMemory. Генерируется, если невозможно
выделить требуемую память.
EOutOfResources. Генерируется при неудачной
попытке создать дескриптор Windows.
Eoverflow. Переполнение при работе с числами
с плавающей точкой (значение слишком
велико) .
EPackageError. Генеруруется при возникновении
ошибок, связанных с пакетами.
Eprinter. Указывает на ошибку, возникшую во
время печати.
Eprivilege. Генерируется при нарушении
уровней привилегии процессора, например
если присваимаемое значение выходит за
рамки допустимых или имеет некорректный
тип данных.
EPropReadOnly. Указывает на попытку записи в
свойство, предназначенное только для
чтения (при использовании технологии OLE).
EPropWriteOnly. Указывает на попытку чтения из
свойства, предназначенного только для
записи (при использовании технологии OLE).
ERangeError. Значение, выходящее за
допустимые рамки, для индексирования
массива или короткой строки, а также для
присвоения переменным скалярного или
перечислимого типа. Эта исключительная
ситуация не генерируется для длинных
строк.Чтобы исключительная ситуация была
сгенерирована, программа должна
компилироваться с директивой {$R+}, что
обычно делается только во время отладки.
По умолчанию используется директива
{$R-}, а это исключает проверку диапазонов и
соответсвенно возможность возникновения
этой исключительной ситуации.
EReadError. Генерируется при некорректной
попытке считать данные потока, а также
если невозможно считать данные свойства
при создании обьекта формы.
ERegistryException. Указывает на ошибку при
выполнении операций с реестром Windows,
такую как попытка изменить область
реестра с несоответствующими
привилегиями пользователя.
EResNotFound. Генерируется, если определенный
ресурс, например пиктограмма, не найден.
Распространенная причина этой
исключительной ситуации - удаленная или
закомментированная директива {$R*.DFM} в
разделе implementation модуля формы.
ESocketError. Указывает на ошибку при работе с
обьектом сокета Windows.
EStackOverflow. Генерируется, если стек
текущего потока достиг последней
страницы памяти, т.е. программе грозит
нехватка памяти. Причиной этой проблемы
обычно являются большие локальные
переменные в процедурах и функциях , а
также глубоко вложенные рекурсивные
подпрограммы.(Переместите большие
переменные в глобальную область).
EStreamError. Базовый класс для ошибок
файловых потоков. Обьект этого класса
создается, если не удается выделить поток.
EStringListError. Указывает на ошибку в
операциях со строковым списком, например
при обращении к списку по неверному
индексу.
Ethread. Указывает на проблему, связанную с
синхронизацией потоков.
ETreeViewError. Генерируется при использовании
неверного индекса для компонента TreeView.
Eunderflow. Потеря значимости при операциях с
числами с плавающей точкой (значение
слишком мало).
EVariantError. Указывает на ошибку, связанную с
неверным использованием вариантного
типа данных, например на такую, как
неверное приведение типа, или индекс,
выходящий за пределы индексного
пространства.
EWin32Error. Генерируется при возникновении
ошибки Windows. Обработчиком по умолчанию
выводится диалоговое окно с кодом ошибки
и строкой сообщения. Чтобы получить
сообщение операционной системы, можно
использовать функцию Win32Check из модуля
SysUtils.
EWriteError. Генерируется при ошибках записи
в файловый поток.
EZeroDivide. Деление на нуль при операциях с
числами с плавающей точкой.
|