Tr

Try/Rescue σε Elixir

1 άσκηση

Σχετικά με την έννοια Try/Rescue

Μπορείς να χρησιμοποιήσεις το try .. rescue για να πιάσεις και να αξιολογήσεις σφάλματα που πετιούνται μέσα σε ένα μπλοκ.

Για παράδειγμα:

try do
  raise RuntimeError, "error"
rescue
  e in RuntimeError -> :error
end
  • Γραμμή 1, το μπλοκ δηλώνεται με το try.
  • Γραμμή 2, εδώ τοποθετείται η κλήση συνάρτησης που μπορεί να δημιουργήσει ένα σφάλμα, στην προκειμένη περίπτωση καλούμε τη raise/1.
  • Γραμμή 4, στο τμήμα rescue, κάνουμε αντιστοίχιση μοτίβου στο όνομα Module του σφάλματος που πετάχτηκε
    • στην αριστερή πλευρά του ->:
      • το e αντιστοιχίζεται στο struct του σφάλματος.
      • το in είναι λέξη-κλειδί.
      • το RuntimeError είναι το module που πρέπει να ταιριάξει, αλλά μπορεί να ταιριάξει με οποιοδήποτε module σφάλματος, ή με _ για όλα τα σφάλματα.
    • στη δεξιά πλευρά:
      • οι εντολές που εκτελούνται αν το σφάλμα ταιριάξει.

Struct σφαλμάτων

Τα σφάλματα (που μερικές φορές ονομάζονται και "εξαιρέσεις") που πιάνεις με αυτόν τον τρόπο είναι struct. Διαφορετικά struct σφαλμάτων έχουν διαφορετικά κλειδιά. Στη "ενότητα εξαιρέσεων" της βασικής βιβλιοθήκης μπορείς να βρεις μια λίστα με όλα τα προκαθορισμένα σφάλματα.

# ArithmeticError caused by division by zero
%ArithmeticError{message: "bad argument in arithmetic expression"}

# Protocol.UndefinedError caused by passing `nil` to `Enum.count/1`
%Protocol.UndefinedError{description: "", protocol: Enumerable, value: nil}

Το να πιάνεις σφάλματα στην Elixir συμβαίνει πολύ σπάνια. Συνήθως το σφάλμα που πιάνεται καταγράφεται ή αποστέλλεται σε μια εξωτερική υπηρεσία παρακολούθησης και μετά ξαναπετιέται. Αυτό σημαίνει ότι συνήθως δεν μας ενδιαφέρει η εσωτερική δομή του συγκεκριμένου struct σφάλματος.

Η έννοια Εξαιρέσεις περιγράφει πώς να ορίσεις προσαρμοσμένα struct σφαλμάτων.

Απόφυγε τα αντιπρότυπα

  • Απόφυγε προγραμματιστικά μοτίβα που χρησιμοποιούν σφάλματα για να ελέγξουν τη λογική ροή. Αυτό αποτελεί αντιπρότυπο στην Elixir.

    # Avoid using errors for control-flow.
    try do
      {:ok, value} = MyModule.janky_function()
      "All good! #{value}."
    rescue
      e in RuntimeError ->
        reason = e.message
        "Uh oh! #{reason}."
    end
    
    # Rather, use control-flow structures for control-flow.
    case MyModule.janky_function() do
      {:ok, value} -> "All good! #{value}."
      {:error, reason} -> "Uh oh! #{reason}."
    end
    

Να πετάξεις ή να μην πετάξεις, ιδού το ερώτημα

Όπως αναφέρεται στον οδηγό εκκίνησης της Elixir:

Εναπόκειται στην εφαρμογή σου να αποφασίσει αν ένα σφάλμα κατά την [εκτέλεση μιας ενέργειας] αποτελεί εξαίρεση ή όχι. Γι' αυτό η Elixir δεν επιβάλλει εξαιρέσεις στις [...] συναρτήσεις. Αντ' αυτού, αφήνει στον προγραμματιστή να επιλέξει τον καλύτερο τρόπο για να προχωρήσει.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Try/Rescue