다음을 통해 공유


오류 처리

M 식을 계산한 결과는 다음 결과 중 하나를 생성합니다.

  • 단일 값이 생성됩니다.

  • 식을 평가하는 프로세스가 값을 생성할 수 없음을 나타내는 오류가 발생합니다. 오류에는 불완전한 평가의 원인에 대한 추가 정보를 제공하는 데 사용할 수 있는 단일 레코드 값이 포함되어 있습니다.

식 내에서 오류가 발생할 수 있으며 식 내에서 처리할 수 있습니다.

오류 발생

오류를 발생시키는 구문은 다음과 같습니다.

error-raising-expression:
      errorexpression

텍스트 값은 오류 값의 약식으로 사용할 수 있습니다. 예시:

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 변수(집합적으로 항목)에 도달합니다. 항목에 오류가 있는 것으로 표시되고 오류 값이 해당 항목과 함께 저장된 다음 전파됩니다. 해당 항목에 대한 후속 액세스로 인해 동일한 오류가 발생합니다. 레코드, 섹션 또는 let 식의 다른 항목은 반드시 영향을 받지 않습니다(이전에 오류가 있는 것으로 표시된 항목에 액세스하지 않는 한).

  • 최상위 식에 도달합니다. 이 경우 최상위 식을 계산한 결과는 값 대신 오류입니다.

  • 식에 try 도달했습니다. 이 경우 오류가 캡처되어 값으로 반환됩니다.

오류 처리

오류 처리 식(비공식적으로 "try 식")은 오류를 처리하는 데 사용됩니다.

error-handling-expression:
      tryprotected-expression error-handleropt
protected-expression:
      식
error-handler:
      otherwise-clause
      catch 절
otherwise-clause:

      otherwisedefault-expression
default-expression:
      expression
catch 절:
      catchcatch-function
catch-function:
      (parameter-nameopt)=>function-body

다음은 오류 처리기 없이 오류 처리 식을 평가할 때 유지됩니다.

  • protected 식평가에서 오류가 발생하지 않고 x 값을 생성하는 경우 error-handling-expression에서 생성된 값은 다음 형식의 레코드입니다.
    [ HasErrors = false, Value = x ]
  • protected 식의 평가에서 오류 값 e를 발생시키는 경우 error-handling-expression결과는 다음 형식의 레코드입니다.
    [ HasErrors = true, Error = e ]

다음은 오류 처리기를 사용하여 오류 처리 식을평가할 때 유지됩니다.

  • 보호된 식오류 처리기 전에 평가해야 합니다.

  • protected 식의 평가에서 오류가 발생하는 경우에만 오류 처리기를 평가해야 합니다.

  • protected 식평가에서 오류가 발생하는 경우 오류 처리 식에서 생성된 값은 오류 처리기를 평가한 결과입니다.

  • 오류 처리기를 평가하는 동안 발생한 오류가 전파됩니다.

  • 평가되는 오류 처리기가 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-function과 함께 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-함수가 0인 catch 절은 실제로 otherwise 절에 대한 더 길고 대체 구문입니다.

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"

레코드 오류 및 이니셜라이저 허용

다음 예제에서는 오류를 발생시키고 다른 두 필드와 함께 액세스되는 필드 ABC가 있는 레코드 이니셜라이저를 보여 줍니다. 필드는 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바로 가기로 사용할 수 있습니다.

구현되지 않은 식:
      ...

예를 들어 다음 예제는 이전 예제와 동일합니다.

(x, y) => if x > y then x - y else ...