Исключения: создание и повторная обработка функций

  • Функция 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 блоке конструкций trywith/в вычисляемых списках, массивах, последовательностях или вычислительных выражениях, включая 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@()

См. также