Hata İşleme

M ifadesini değerlendirmenin sonucu aşağıdaki sonuçlardan birini oluşturur:

  • Tek bir değer oluşturulur.

  • İfadeyi değerlendirme işleminin bir değer üretemediğini belirten bir hata oluşur. Hata, eksik değerlendirmeye neyin neden olduğu hakkında ek bilgi sağlamak için kullanılabilecek tek bir kayıt değeri içeriyor.

Hatalar bir ifadenin içinden oluşturulabilir ve bir ifadenin içinden işlenebilir.

Hata oluşturma

Hata oluşturma söz dizimi aşağıdaki gibidir:

error-raising-expression:
      errorIfa -de

Metin değerleri hata değerleri için kısaltma olarak kullanılabilir. Örnek:

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

Tam hata değerleri kayıtlardır ve işlevi kullanılarak Error.Record oluşturulabilir:

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

Yukarıdaki ifade şu ifadeyle eşdeğerdir:

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

Hatanın oluşturulması geçerli ifade değerlendirmesinin durmasına neden olur ve ifade değerlendirme yığını aşağıdakilerden biri gerçekleşene kadar geri sarılır:

  • Bir kayıt alanına, bölüm üyesine veya let değişkenine (toplu olarak: bir girdi) ulaşılır. Girdi hata veriyor olarak işaretlenir, hata değeri bu girdiyle birlikte kaydedilir ve sonra yayılır. Bu girdiye daha sonra yapılan tüm erişimler aynı hatanın ortaya alınmasına neden olur. Kaydın, bölümün veya let ifadesinin diğer girişleri etkilenmez (daha önce hatayla işaretlenmiş bir girişe erişmedikleri sürece).

  • Üst düzey ifadeye ulaşılır. Bu durumda, en üst düzey ifadeyi değerlendirmenin sonucu değer yerine bir hatadır.

  • bir try ifadeye ulaşıldı. Bu durumda hata yakalanır ve değer olarak döndürülür.

Hataları işleme

Bir hatayı işlemek için bir hata işleme ifadesi (resmi olmayan bir şekilde "try ifadesi" olarak bilinir) kullanılır:

error-handling-expression:
      tryprotected-expression error-handleropt
protected-expression:
      ifade
hata işleyicisi:
      otherwise yan tümcesi
      catch-yan tümcesi
otherwise-yan tümcesi:

      otherwisedefault-expression
default-expression:
      Ifa -de
catch-yan tümcesi:
      catchcatch-function
catch-function:
      (parametre-adıopt)=>işlev gövdesi

Hata işleyicisi olmadan bir hata işleme-ifadesi değerlendirilirken aşağıdakiler geçerlidir:

  • Korumalı ifadenin değerlendirmesi bir hataya neden olmazsa ve x değeri üretirse, error-handling-expression tarafından üretilen değer aşağıdaki formun kaydıdır:
    [ HasErrors = false, Value = x ]
  • Korumalı ifadenin değerlendirmesi bir hata değeri oluşturursa e, error-handling-expression sonucu aşağıdaki formun kaydıdır:
    [ HasErrors = true, Error = e ]

Hata işleyicisi ile bir hata işleme-ifadesi değerlendirilirken aşağıdakiler geçerlidir:

  • Korumalı ifade, hata işleyiciden önce değerlendirilmelidir.

  • Hata işleyicisi, yalnızca korumalı ifadenin değerlendirmesi bir hata oluşturursa değerlendirilmelidir.

  • Korumalı ifadenin değerlendirmesi bir hata oluşturursa, error-handling-expression tarafından üretilen değer hata işleyicisinin değerlendirilmesinin sonucudur.

  • Hata işleyicisinin değerlendirilmesi sırasında oluşan hatalar yayılır.

  • Değerlendirilen hata işleyicisi bir catch-yan tümcesi olduğunda catch-function çağrılır. Bu işlev bir parametre kabul ederse, hata değeri değeri olarak geçirilir.

Aşağıdaki örnekte hatanın oluşmadığı bir durumda hata işleme-ifadesi gösterilmektedir:

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

Aşağıdaki örnekte bir hatanın oluşturulması ve ardından işlenmesi gösterilmektedir:

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

Yukarıdaki örnek, parametre kabul eden bir catch-function ile catch-yan tümcesi kullanılarak daha az söz dizimi ile yeniden yazılabilir:

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

Aksi durumda yan tümcesi , bir try ifadesi tarafından işlenen hataları alternatif bir değerle değiştirmek için kullanılabilir:

try error "A" otherwise 1 
// 1

Sıfır parametreli catch-function içeren catch-yan tümcesi, otherwise yan tümcesi için daha uzun ve alternatif bir söz dizimidir:

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

Hata işleyicisi de bir hata oluşturursa, try ifadesinin tamamı da şu şekilde olur:

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"

Kayıttaki hatalar ve başlatıcıların izin verme

Aşağıdaki örnekte, hata oluşturan ve ve ile diğer iki alan BCtarafından erişilen bir alan A içeren bir kayıt başlatıcı gösterilmektedir. Alan B tarafından Aoluşturulan hatayı işlemez, ancak C işler. Son alan D erişmiyor A ve bu nedenle içindeki Ahatadan etkilenmez.

[ 
    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 
]

Yukarıdaki ifadeyi değerlendirmenin sonucu:

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

M'de hata işleme, gecikmeli alan başlatma ve ertelenen kapatma değerlendirmelerinin etkileriyle başa çıkmak için hataların nedenine yakın bir şekilde gerçekleştirilmelidir. Aşağıdaki örnekte, bir ifade kullanarak bir hatayı işlemeye yönelik başarısız bir try girişim gösterilmektedir:

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

Bu örnekte tanımın g çağrılırken fortaya çıkarılan hatayı işlemesi amaçlanmıştır. Ancak hata, yalnızca gerektiğinde ve dolayısıyla kayıt f'den döndürüldükten ve ifadeden try geçirildikten sonra çalışan bir alan başlatıcısı tarafından oluşturulur.

Uygulanmadı hatası

bir ifade geliştirilirken, bir yazar ifadenin bazı bölümleri için uygulamayı dışarıda bırakmak isteyebilir, ancak yine de ifadeyi yürütebilmek isteyebilir. Bu durumu işlemenin bir yolu, tanımlanamayan parçalar için hata vermektir. Örnek:

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

Üç nokta simgesi (...) için errorkısayol olarak kullanılabilir.

not-implemented-expression:
      ...

Örneğin, aşağıdakiler önceki örne eşdeğerdir:

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