Я обнаружил, что это довольно понятно и в то же время непонятно, - это отсутствие статей, примеров или всего, что упоминало бы, как обрабатывать исключение в ReasonML. По своей природе я не вижу особого использования кода записи исключений в ReasonML. Однако этого нельзя избежать, когда мы хотим взаимодействовать с JavaScript.

Поскольку я не могу найти формальную грамматику исключения ReasonML, я вернусь к определению исключение OCaml.

в Ocaml Exception - это просто расширяемый вариант типаexn

Чтобы обработать исключение в OCaml, мы можем использовать конструкцию try/with, которая напоминает сопоставление с шаблоном:

try <expr> with
| <pat1> -> <expr1>
| <pat2> -> <expr2>
...

В ReasonML мы используем следующее предложение:

try (<expr>) {
| <pat1> => <expr1>
| <pat2> => <expr2>
...
}

expr оценивается и проверяется. Если возникает исключение, оно пытается сопоставить данный шаблон (помните, что это обычное сопоставление с шаблоном с ограничением встроенного типа exn). В противном случае результатом будет оценка expr. Следующий код - это пример того, как использовать исключение в синтаксисе ReasonML.

try (f) {
| SomeExn => doSomething()
| AnotherExn(value) => doSomethingWith(value)
...
}

Шаблон в предложении должен быть только типа exn. Позже мы покажем, что это ключевое слово можно заменить на switch типа исключения.

Определите тип исключения, используя ключевое слово exception

Чтобы работать с исключениями, мы должны сначала знать, как их определить. Это просто, как определить тип. Фактически, exception - это синтаксический сахар для добавления нового типа в exn.. Рассмотрим следующий код:

type exn +=
  | MyError;
exception MyAnotherError;

Первые две строки предназначены для добавления нового типа с именем MyError с использованием синтаксиса расширяемого варианта. Строка ниже делает то же самое, но с использованием ключевого слова exception. Как мы видим из аналога JavaScript:

var MyError = Caml_exceptions.create("MyError");
var MyAnotherError = Caml_exceptions.create("MyAnotherError");

exception Определение - это определение любого исключения, которое мы хотим придать смысл нашей программе. Однако, чтобы иметь дело с исключениями из JavaScript, мы должны обрабатывать Js.Exn.Error(t)

Обработка исключения со стороны JavaScript

Большинство исключений, поднятых со стороны JavaScript, станут значениями типа Js.Exn.Error(t). Предположим, что в сценарии мы хотим использовать функцию JavaScript, которая может генерировать исключение.

exports.func = function(x) {
    throw new Error("My Js Error");
    return x;
}

Нам нужно правильно обработать это исключение.

[@bs.module "./test.js"] external func: (string) => string = "func";
let result = try(func("test"){
|Js.Exn.Error(err) => Js.Exn.message(err) 
   |> Js.Option.getWithDefault("Some Js Error");""
|x => failwith(x);"Other Error"
}

Приведенный выше код импортирует functionfunc, который является функцией JavaScript, и использует конструкцию try, чтобы проверить, вызывает ли она исключение. Если выбрано исключение типа Js.Exn.Error, мы будем использовать Js.Exn.message для извлечения сообщения об ошибке. В противном случае будут failwith исключения любого другого типа.

Обратите внимание, что результат try должен быть того же типа, что и результат func, в данном случае string.

Чтобы понять, почему, давайте развернем try до нормального сопоставления с образцом. Мы можем добиться того же поведения, используя сопоставление с образцом следующим образом:

[@bs.module "./test.js"] external func: (string) => string = "func";
let result = switch(func("test")){
| exception(Js.Exn.Error(err)) => Js.Exn.message(err)
   |> Js.Option.getWithDefault("Some Js Error");""
| exception(x) => failwith(x);"Other Error"
| value => value
}

Теперь все имеет больше смысла, потому что value => value предполагает, что тип этой оценки должен возвращать value типа func результата.

Надеюсь, это будет полезно, когда вы пытаетесь использовать Google для обработки исключений ReasonML. Вот и вся причина, по которой я написал это. Не стесняйтесь оставлять мне любые комментарии или предложения. Спасибо!