Χειρισμός σφαλμάτων
Το αποτέλεσμα της αξιολόγησης μιας παράστασης M παράγει ένα από τα παρακάτω αποτελέσματα:
Παράγεται μία μόνο τιμή.
Προκαλείται σφάλμα, υποδεικνύοντας ότι η διαδικασία αξιολόγησης της παράστασης δεν ήταν δυνατή να δημιουργήσει μια τιμή. Ένα σφάλμα περιέχει μια μοναδική τιμή εγγραφής που μπορεί να χρησιμοποιηθεί για την παροχή πρόσθετων πληροφοριών σχετικά με το τι προκάλεσε την ελλιπή αξιολόγηση.
Τα σφάλματα μπορούν να προκληθούν μέσα από μια παράσταση και ο χειρισμός τους είναι δυνατός μέσα από μια παράσταση.
Εμφάνιση σφαλμάτων
Η σύνταξη για την εμφάνιση ενός σφάλματος είναι η εξής:
παράσταση-εμφάνισης-σφάλματος:
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, συλλογικά: μια καταχώρηση. Η καταχώρηση επισημαίνεται ως σφάλμα, η τιμή σφάλματος αποθηκεύεται με αυτήν την καταχώρηση και, στη συνέχεια, μεταδίδεται. Οποιαδήποτε μεταγενέστερη πρόσβαση σε αυτήν την καταχώρηση θα προκαλέσει την εμφάνιση ενός πανομοιότυπου σφάλματος. Άλλες καταχωρήσεις της εγγραφής, της ενότητας ή της παράστασης let δεν επηρεάζονται απαραίτητα (εκτός εάν αποκτούν πρόσβαση σε μια καταχώρηση που έχει προηγουμένως επισημανθεί ως σφάλμα).
Επιτυγχάνεται η παράσταση ανώτατου επιπέδου. Σε αυτή την περίπτωση, το αποτέλεσμα της αξιολόγησης της παράστασης ανώτατου επιπέδου είναι ένα σφάλμα αντί για μια τιμή.
Επιτυγχάνεται μια
try
παράσταση. Σε αυτή την περίπτωση, το σφάλμα καταγράφεται και επιστρέφεται ως τιμή.
Χειρισμός σφαλμάτων
Μια παράσταση-χειρισμού-σφάλματος (ανεπίσημα γνωστή ως "παράσταση try") χρησιμοποιείται για τον χειρισμό ενός σφάλματος:
παράσταση-χειρισμού-σφάλματος:
try
προστατευμένη-παράσταση επιλογή χειρισμού σφαλμάτων
προστατευμένη-παράσταση:
έκφραση
χειρισμός σφαλμάτων:
όρος-otherwise
όρος catch
όρος-otherwise:
otherwise
προεπιλεγμένη-παράσταση
προεπιλεγμένη-παράσταση:
έκφραση
όρος catch:
catch
συνάρτηση catch-
συνάρτηση catch-:
(
όνομα-παραμέτρουπροα opt =>
)
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-with μια συνάρτηση-catch που αποδέχεται μια παράμετρο:
let
x = try error "A" catch (e) => e
in
x
// [ Reason = "Expression.Error", Message = "A", Detail = null ]
Ένας όρος-otherwise μπορεί να χρησιμοποιηθεί για την αντικατάσταση σφαλμάτων που χειρίζεται μια παράσταση try με μια εναλλακτική τιμή:
try error "A" otherwise 1
// 1
Ένας όρος-catch με μια συνάρτηση-catch-zero-parameter είναι στην πραγματικότητα μια μεγαλύτερη, εναλλακτική σύνταξη για έναν όρο-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"
Σφάλματα στις προετοιμασίας εγγραφής και let
Το παρακάτω παράδειγμα εμφανίζει μια προετοιμασία εγγραφής με ένα πεδίο 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
το .
μη υλοποιημένη-παράσταση:
...
Για παράδειγμα, το παρακάτω ισοδυναμεί με το προηγούμενο παράδειγμα:
(x, y) => if x > y then x - y else ...