Исключения: создание и повторная обработка функций
- Функция
raise
используется для указания того, что произошла ошибка или исключительное условие. Сведения об ошибке фиксируются в объекте исключения. - Функция
reraise
используется для распространения обработанного исключения по цепочке вызовов.
Синтаксис
raise (expression)
Замечания
Функция raise
создает объект исключения и инициирует процесс очистки стека. Процесс очистки стека управляется средой CLR, поэтому поведение этого процесса совпадает с любым другим языком .NET. Процесс очистки стека — это поиск обработчика исключений, который соответствует созданному исключению. Поиск начинается в текущем try...with
выражении, если есть один. Каждый шаблон в блоке with
проверка по порядку. При обнаружении соответствующего обработчика исключений исключение считается обработанным; в противном случае стек не вызывается и with
блокирует цепочку вызовов проверка до тех пор, пока не будет найден соответствующий обработчик. Все finally
блоки, встречающиеся в цепочке вызовов, также выполняются в последовательности, так как стек распаковывается.
Функция raise
эквивалентна throw
в C# или C++.
В следующих примерах кода показано использование raise
функции для создания исключения.
exception InnerError of string
exception OuterError of string
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
function2 100 100
function2 100 10
Функцию raise
можно также использовать для создания исключений .NET, как показано в следующем примере.
let divide x y =
if (y = 0) then raise (System.ArgumentException("Divisor cannot be zero!"))
else
x / y
Повторная обработка исключения
Функцию reraise
можно использовать в блоке with
для распространения обработанного исключения по цепочке вызовов.
reraise
не принимает операнды исключений. Это наиболее полезно, когда метод передает аргумент от вызывающего метода к другому методу библиотеки, а метод библиотеки вызывает исключение, которое должно быть передано вызывающему объекту.
Функция reraise
не может использоваться в with
блоке конструкций try
with
/в вычисляемых списках, массивах, последовательностях или вычислительных выражениях, включая task { .. }
или.async { .. }
open System
let getFirstCharacter(value: string) =
try
value[0]
with :? IndexOutOfRangeException as e ->
reraise()
let s = getFirstCharacter("")
Console.WriteLine($"The first character is {s}")
// The example displays the following output:
// System.IndexOutOfRangeException: Index was outside the bounds of the array.
// at System.String.get_Chars(Int32 index)
// at getFirstCharacter(String value)
// at <StartupCode>.main@()