Del via


Feilhåndtering

Resultatet av evalueringen av et M-uttrykk gir ett av følgende resultater:

  • En enkeltverdi produseres.

  • Det oppstår en feil som angir at prosessen med å evaluere uttrykket ikke kan produsere en verdi. En feil inneholder én enkelt postverdi som kan brukes til å gi tilleggsinformasjon om hva som forårsaket den ufullstendige evalueringen.

Feil kan utløses fra et uttrykk, og kan håndteres fra et uttrykk.

Oppheving av feil

Syntaksen for å øke en feil er som følger:

error-raising-expression:
      error uttrykk

Tekstverdier kan brukes som shorthand for feilverdier. Eksempel:

error "Hello, world" // error with message "Hello, world"

Fullstendige feilverdier er poster og kan konstrueres ved hjelp av Error.Record funksjonen:

error Error.Record("FileNotFound", "File my.txt not found",
     "my.txt")

Uttrykket ovenfor tilsvarer:

error [ 
    Reason = "FileNotFound", 
    Message = "File my.txt not found", 
    Detail = "my.txt" 
]

Hvis du øker en feil, stoppes den gjeldende uttrykksevalueringen, og uttrykksevalueringsstakken avvikles til ett av følgende oppstår:

  • Et postfelt, et delmedlem eller en la-variabel – samlet: en oppføring – nås. Oppføringen er merket som å ha en feil, feilverdien lagres med denne oppføringen og overføres deretter. Eventuell etterfølgende tilgang til denne oppføringen vil føre til at en identisk feil utløses. Andre oppføringer i posten, inndelingen eller la uttrykket påvirkes ikke nødvendigvis (med mindre de har tilgang til en oppføring som tidligere ble merket som å ha en feil).

  • Uttrykket på øverste nivå er nådd. I dette tilfellet er resultatet av evalueringen av uttrykket på øverste nivå en feil i stedet for en verdi.

  • Et try uttrykk er nådd. I dette tilfellet fanges feilen opp og returneres som en verdi.

Håndtere feil

Et feilbehandlingsuttrykk (uformelt kjent som et «prøveuttrykk») brukes til å håndtere en feil:

feilbehandlingsuttrykk:
      tryvalg av feilbehandlingfor beskyttet uttrykk
beskyttet uttrykk:
      uttrykk
feilbehandling:
      ellers-setningsdel
      catch-clause
ellers-setningsdel:

      otherwisestandarduttrykk
standarduttrykk:
      uttrykk
catch-clause:
      catchcatch-function
catch-funksjon:
      (parameternavnopt =>) function-body

Følgende gjelder når du evaluerer et feilhåndteringsuttrykk uten feilbehandling:

  • Hvis evalueringen av det beskyttede uttrykket ikke resulterer i en feil og produserer en verdi x, er verdien som produseres av feilbehandlingsuttrykket , en post i følgende skjema:
    [ HasErrors = false, Value = x ]
  • Hvis evalueringen av det beskyttede uttrykket øker en feilverdi e, er resultatet av feilbehandlingsuttrykket en post i følgende skjema:
    [ HasErrors = true, Error = e ]

Følgende gjelder når du evaluerer et feilhåndteringsuttrykk med en feilbehandling:

  • Det beskyttede uttrykket må evalueres før feilbehandlingen.

  • Feilbehandlingen må evalueres hvis og bare hvis evalueringen av det beskyttede uttrykket fører til en feil.

  • Hvis evalueringen av det beskyttede uttrykket fører til en feil, er verdien som produseres av feilbehandlingsuttrykket, resultatet av evalueringen av feilbehandlingen.

  • Feil som oppstår under evalueringen av feilbehandlingen, overføres.

  • Når feilbehandlingen som evalueres, er en catch-setningsdel, aktiveres catch-funksjonen. Hvis denne funksjonen godtar en parameter, sendes feilverdien som verdien.

Følgende eksempel illustrerer et feilbehandlingsuttrykk i et tilfelle der det ikke oppstår noen feil:

let
    x = try "A"
in
    if x[HasError] then x[Error] else x[Value] 
// "A"

Følgende eksempel viser hvordan du reiser en feil og håndterer den:

let
    x = try error "A" 
in
    if x[HasError] then x[Error] else x[Value] 
// [ Reason = "Expression.Error", Message = "A", Detail = null ]

Det foregående eksemplet kan skrives om med mindre syntaks ved hjelp av en catch-setningsdel med en catch-funksjon som godtar en parameter:

let
    x = try error "A" catch (e) => e
in
    x
// [ Reason = "Expression.Error", Message = "A", Detail = null ]

En ellers-setningsdel kan brukes til å erstatte feil som håndteres av et prøveuttrykk med en alternativ verdi:

try error "A" otherwise 1 
// 1

En catch-setning med en null-parameter catch-funksjon er effektivt en lengre, alternativ syntaks for en ellers-setningsdel:

try error "A" catch () => 1 
// 1

Hvis feilbehandlingen også oppstår en feil, gjør hele prøveuttrykket også:

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"

Feil i post og la initialiserere

Eksemplet nedenfor viser en postinitialiserer med et felt A som utløser en feil og åpnes av to andre felt B og C. Feltet B håndterer ikke feilen som utløses av A, men C gjør det. Det endelige feltet D får ikke tilgang til A det, og påvirkes derfor ikke av feilen i 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 
]

Resultatet av evalueringen av uttrykket ovenfor er:

[ 
    A = // error with message "A" 
    B = // error with message "A" 
    C = "A", 
    D = 2 
]

Feilbehandling i M bør utføres nær årsaken til feil for å håndtere effekten av lat felt initialisering og utsatt avslutning evalueringer. Følgende eksempel viser et mislykket forsøk på å håndtere en feil ved hjelp av et try uttrykk:

let
    f = (x) => [ a = error "bad", b = x ],
    g = try f(42) otherwise 123
in 
    g[a]  // error "bad"

I dette eksemplet var definisjonen g ment å håndtere feilen som ble utløst når du ringte f. Feilen utløses imidlertid av en feltinitialiserer som bare kjører når det er nødvendig, og dermed etter at posten ble returnert fra f og sendt gjennom try uttrykket.

Feil som ikke er implementert

Mens et uttrykk utvikles, kan det hende at en forfatter vil utelate implementeringen for enkelte deler av uttrykket, men vil kanskje fortsatt kunne kjøre uttrykket. Én måte å håndtere dette tilfellet på, er å opprette en feil for de uimplementerte delene. Eksempel:

(x, y) =>
     if x > y then
         x - y
     else
         error Error.Record("Expression.Error", 
            "Not Implemented")

Ellipsesymbolet (...) kan brukes som en snarvei for error.

ikke implementert-uttrykk:
      ...

Følgende tilsvarer for eksempel det forrige eksemplet:

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