functionmymod(a,b: integer): integer;
begin
ifb = 0 then
raisenew MyModErrorException('Функция mymod: деление на 0');
Result := a - (a divb) * b;
end;
Тогда обработка ошибок будет выглядеть так:
try
readln(a,b);
writeln(mymod(a,b) mod(a-1));
...
except
onSystem.DivideByZeroException do
writeln('Деление на 0');
one: MyModErrorException do
writeln(e.Message);
elsewriteln('какое-то другое исключение')
end;
Если сделать MyModErrorException наследником класса System.ArithmeticException, как и System.DivideByZeroException, то последний код можно упростить:
typeMyModErrorException = class(System.ArithmeticException) end;
...
try
readln(a,b);
writeln(mymod(a,b) mod(a-1));
...
except
one: System.ArithmeticException do
writeln(e.Message);
elsewriteln('Какое-то другое исключение')
end;
Наконец, можно поступить следующим образом. Перехватим в функции mymod исключение System.DivideByZeroException и в ответ сгенерируем новое - MyModErrorException:
functionmymod(a,b: integer): integer;
begin
try
Result := a - (a divb) * b;
except
one: System.DivideByZeroException do
raise newMyModErrorException('Функция mymod: деление на 0');
end;
end;
Стандартные классы исключений
Все классы исключений являются потомками класса System.Exception, включающего следующий интерфейс:
type
Exception = class
public
constructorCreate;
constructorCreate(message: string);
propertyMessage: string; // только на чтение
propertyStackTrace: string; // только на чтение
end;
Свойство Message возвращает сообщение, связанное с объектом исключения.
Свойство StackTrace возвращает стек вызовов подпрограмм на момент генерации исключения.
Ниже приводятся некоторые классы исключений, определенные в пространстве имен System и являющиеся производными от класса System.SystemException:
System.OutOfMemoryException - недостаточно памяти для выполнения программы;
System.StackOverflowException - переполнение стека (как правило, при многократных вложенных вызовах подпрограмм);
System.AccessViolationException - попытка доступа к защищенной памяти;
System.ArgumentException - неверное значение параметра подпрограммы;
System.ArithmeticException - базовый класс всех арифметических исключений. Наследники:
System.DivideByZeroException - целочисленное деление на 0;
System.OverflowException - переполнение при выполнении арифметической операции или преобразования типов;
System.FormatException - неверный формат параметра (например, при преобразовании строки в число);
System.IndexOutOfRangeException - выход за границы диапазона изменения индекса массива;
System.InvalidCastException - неверное приведение типов;
System.NullReferenceException - попытка вызвать метод для нулевого объекта или разыменовать нулевой указатель;
System.IO.IOException - ошибка ввода-вывода. Наследники:
System.IO.IOException.DirectoryNotFoundException - каталог не найден;
System.IO.IOException.EndOfStreamException - попытка чтения за концом потока;
System.IO.IOException.FileNotFoundException - файл не найден.
Исключения, определяемые пользователем
Для определения своего типа исключения достаточно породить класс - наследник класса Exception:
typeMyException = class(Exception) end;
Тело класса-исключения может быть пустым, но, тем не менее, новое имя для типа исключения позволит его разграничить с остальными исключениями:
try
...
except
onMyException do
writeln('Целочисленное деление на 0');
onException do
writeln('Файл отсутствует');
end;
Исключение может содержать дополнительную информацию, связанную с точкой, в которой произошло исключение:
type
FileNotFoundException = class(Exception)
fname: string;
constructorCreate(msg,fn: string);
begin
inheritedCreate(msg);
fname := fn;
end;
end;
...
procedureReadFile(fname: string);
begin
if notFileExists(fname) then
raise newFileNotFoundException('Файл не найден',fname);
end;
...
try
...
except
one: FileNotFoundException do
writeln('Файл '+e.fname+' не найден');
end;
Повторная генерация исключения
Для повторной генерации исключения в блоке exceptслужит оператор raiseбез параметров:
raise;
Например:
try
...
except
onFileNotFoundException do
begin
Читать дальше