Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Результат вычисления выражения M приводит к одному из следующих результатов:
Создается одно значение.
Возникает ошибка, указывающая, что процесс оценки выражения не удалось создать значение. Ошибка содержит одно значение записи, которое можно использовать для предоставления дополнительных сведений о том, что вызвало неполное вычисление.
Ошибки могут возникать из выражения и обрабатываться из выражения.
Создание ошибок
Синтаксис для создания ошибки выглядит следующим образом:
выражение error-raising-expression:
error
выражение
Текстовые значения можно использовать в качестве сокращенных значений ошибок. Например:
error "Hello, world" // error with message "Hello, world"
Полные значения ошибок — это записи и можно создать с помощью Error.Record
функции:
error Error.Record("FileNotFound", "File my.txt not found",
"my.txt")
Приведенное выше выражение эквивалентно следующему:
error [
Reason = "FileNotFound",
Message = "File my.txt not found",
Detail = "my.txt"
]
При возникновении ошибки текущая оценка выражений будет остановлена, и стек вычислений выражений будет отсохнет до тех пор, пока не произойдет одно из следующих действий:
Пока не будет достигнуто поле записи, элемент раздела или переменная let — в совокупности — запись. Запись помечена как ошибка, значение ошибки сохраняется с этой записью, а затем распространяется. Любой последующий доступ к этой записи приведет к возникновению идентичной ошибки. Другие записи записи, раздела или выражения пусть не обязательно затронуты (если они не получают доступ к записи, помеченной как ошибка).
Достигается выражение верхнего уровня. В этом случае результат оценки выражения верхнего уровня является ошибкой вместо значения.
try
Достигается выражение. В этом случае ошибка фиксируется и возвращается в качестве значения.
Обработка ошибок
Выражение обработки ошибок (неофициально известное как "выражение try") используется для обработки ошибки:
Выражение error-handling-expression:
try
Выборобработчика ошибок защищенного выражения
защищенное-выражение:
выражение
Обработчик ошибок:
Предложение в противном случае
предложение catch-
предложение-otherwise:
otherwise
выражение по умолчанию
выражение по умолчанию:
выражение
предложение catch-:
catch
catch-function
catch-function:
(
параметр-nameopt)
=>
function-body
При оценке выражения обработки ошибок без обработчика ошибок следует учитывать следующее:
- Если оценка защищенного выражения не приводит к ошибке и создает значение x, значение, созданное выражением обработки ошибок, является записью следующей формы:
[ HasErrors = false, Value = x ]
- Если оценка защищенного выражения вызывает значение ошибки e, результат выражения обработки ошибок является записью следующей формы:
[ HasErrors = true, Error = e ]
При оценке выражения обработки ошибок с помощью обработчика ошибок содержится следующее:
Перед обработчиком ошибок необходимо оценить защищенное выражение.
Обработчик ошибок должен оцениваться только в том случае, если оценка защищенного выражения вызывает ошибку.
Если оценка защищенного выражения вызывает ошибку, значение, созданное выражением обработки ошибок, является результатом оценки обработчика ошибок.
Ошибки, возникающие во время оценки обработчика ошибок, распространяются.
Когда вычисляемый обработчик ошибок является предложением catch-, вызывается функция catch. Если эта функция принимает параметр, значение ошибки будет передано в качестве значения.
В следующем примере показано выражение обработки ошибок в случае, когда ошибка не возникает:
let
x = try "A"
in
if x[HasError] then x[Error] else x[Value]
// "A"
В следующем примере показано создание ошибки, а затем обработка ошибки:
let
x = try error "A"
in
if x[HasError] then x[Error] else x[Value]
// [ Reason = "Expression.Error", Message = "A", Detail = null ]
Предыдущий пример можно переписать с меньшим синтаксисом с помощью предложения catch-с функцией catch, которая принимает параметр:
let
x = try error "A" catch (e) => e
in
x
// [ Reason = "Expression.Error", Message = "A", Detail = null ]
Предложение в противном случае можно использовать для замены ошибок, обрабатываемых выражением try, альтернативным значением:
try error "A" otherwise 1
// 1
Предложение catch-с нулевым параметром catch-function является более длинным альтернативным синтаксисом для предложения в противном случае:
try error "A" catch () => 1
// 1
Если обработчик ошибок также вызывает ошибку, то выполняется все выражение try:
try error "A" otherwise error "B"
// error with message "B"
try error "A" catch () => error "B"
// error with message "B"
try error "A" catch (e) => error "B"
// error with message "B"
Ошибки в записи и разрешить инициализаторам
В следующем примере показан инициализатор записей с полем A
, которое вызывает ошибку и обращается к двум другим полям B
и C
. Поле B
не обрабатывает ошибку, которая возникает, A
но C
делает. Окончательное поле D
не обращается и A
поэтому оно не влияет на ошибку.A
[
A = error "A",
B = A + 1,
C = let x =
try A in
if not x[HasError] then x[Value]
else x[Error],
D = 1 + 1
]
Результатом оценки приведенного выше выражения является:
[
A = // error with message "A"
B = // error with message "A"
C = "A",
D = 2
]
Обработка ошибок в M должна быть выполнена близко к причине ошибок для устранения последствий инициализации ленивых полей и отложенных вычислений закрытия. В следующем примере показана неудачная попытка обработки ошибки с помощью try
выражения:
let
f = (x) => [ a = error "bad", b = x ],
g = try f(42) otherwise 123
in
g[a] // error "bad"
В этом примере определение g
было предназначено для обработки ошибки, возникаемой при вызове f
. Однако ошибка вызывается инициализатором полей, который выполняется только при необходимости и таким образом после возврата записи из f и передается через try
выражение.
Не реализована ошибка
Несмотря на разработку выражения, автор может отказаться от реализации для некоторых частей выражения, но может по-прежнему иметь возможность выполнять выражение. Один из способов обработки этого дела — вызвать ошибку для неимблированных частей. Например:
(x, y) =>
if x > y then
x - y
else
error Error.Record("Expression.Error",
"Not Implemented")
Символ многоточия (...
) можно использовать в качестве ярлыка error
.
not-implemented-expression:
...
Например, следующий пример эквивалентен предыдущему примеру:
(x, y) => if x > y then x - y else ...