Διαδρομές
/
Roc
Roc
/
Ασκήσεις
/
Διαχείριση Σφαλμάτων
Διαχείριση Σφαλμάτων

Διαχείριση Σφαλμάτων

Μέτριο

Οδηγίες

Υλοποίησε διάφορα είδη χειρισμού σφαλμάτων και διαχείρισης πόρων.

Ένα σημαντικό σημείο του προγραμματισμού είναι το πώς να χειρίζεσαι τα σφάλματα και να κλείνεις πόρους ακόμα κι αν συμβούν σφάλματα.

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

Υλοποίηση

Φτιάχνεις έναν μικροσκοπικό διακομιστή ιστού που αναζητά σε μια ακόμα πιο μικροσκοπική βάση δεδομένων χρηστών. Ακούγεται εύκολο, αλλά στον πραγματικό κόσμο πολλά μπορούν (και συχνά συμβαίνει) να πάνε στραβά:

  • η σύνδεση μπορεί να μην είναι ασφαλής: το URL πρέπει να ξεκινά με "https://"
  • το όνομα τομέα μπορεί να μην είναι έγκυρο: σε αυτή την άσκηση, θα πρέπει να είναι "example.com"
  • η σελίδα μπορεί να μη βρεθεί: επιτρέπονται μόνο τα "https://example.com/", "https://example.com/users/" και "https://example.com/users/<user_id>"
  • το user_id μπορεί να μην είναι θετικός ακέραιος
  • μπορεί να μην υπάρχει κανένας χρήστης στη βάση δεδομένων με αυτό το user_id

Όταν κάτι πάει στραβά, είναι σημαντικό να δώσεις στον τελικό χρήστη ένα ωραίο και κατατοπιστικό μήνυμα σφάλματος, ώστε να μπορέσει να λύσει το πρόβλημα. Γι' αυτό, πρέπει να βεβαιωθείς ότι ο κώδικάς σου διαδίδει κατατοπιστικά σφάλματα από το σημείο όπου εντοπίζεται το σφάλμα ως το σημείο όπου παράγεται το μήνυμα σφάλματος.

Ευτυχώς, η Roc σου επιτρέπει να μεταφέρεις ωφέλιμο φορτίο (δηλαδή δεδομένα) μέσα στην ετικέτα Err σου. Είναι δελεαστικό να μεταφέρεις απευθείας ένα μήνυμα σφάλματος (π.χ. Err("User #42 was not found")), και αυτό μπορεί να είναι εντάξει σε μερικές απλές περιπτώσεις, αλλά έχει αρκετούς περιορισμούς:

  • μπορεί να μην έχεις αρκετό πλαίσιο μέσα στη συνάρτηση που εντοπίζει το σφάλμα, ώστε να παράγεις ένα αρκούντως κατατοπιστικό μήνυμα σφάλματος.
    • Για παράδειγμα, η συνάρτηση Str.to_u64 μπορεί να χρησιμοποιηθεί για να αναλύσει κάθε λογής ακέραιους: ημέρες, δευτερόλεπτα, αναγνωριστικά χρήστη και άλλα. Αν το μήνυμα σφάλματος λέει απλώς Could not convert string "0.5" to a positive integer, ο χρήστης μπορεί να μην έχει αρκετό πλαίσιο για να λύσει το πρόβλημα.
  • σε πολλές περιπτώσεις ο κώδικας χειρισμού σφαλμάτων σου μπορεί να χρειαστεί να χειριστεί κάποια σφάλματα διαφορετικά από άλλα. Ωστόσο, αν τα σφάλματα μεταφέρουν μόνο συμβολοσειρές ως ωφέλιμο φορτίο, ο κώδικας χειρισμού σφαλμάτων σου θα πρέπει να αναλύσει αυτή τη συμβολοσειρά για να μάθει τι πρόβλημα προέκυψε: αυτό είναι αναποτελεσματικό και μπορεί εύκολα να σπάσει αν το μήνυμα σφάλματος τροποποιηθεί ποτέ.
  • αν ο ιστότοπός σου είναι πολύγλωσσος, θα χρειαστεί να μεταφράσεις το μήνυμα σφάλματος στη γλώσσα του χρήστη. Θα είναι πολύ πιο εύκολο να το κάνεις αυτό αν το ωφέλιμο φορτίο του σφάλματος είναι δεδομένα φιλικά προς τη μηχανή και όχι μια αγγλική συμβολοσειρά.

Έτσι, σε αυτή την άσκηση, τα σφάλματά σου θα μεταφέρουν αντίθετα μια ετικέτα με νόημα μαζί με το δικό της κατατοπιστικό ωφέλιμο φορτίο. Για παράδειγμα, αν ο χρήστης δεν βρεθεί, το σφάλμα θα μοιάζει με Err(UserNotFound(42)).

Εντάξει, ας ξεκινήσουμε! Να τι πρέπει να κάνεις:

  1. Υλοποίησε τη get_user ώστε να επιστρέφει τον ζητούμενο χρήστη από τη users "βάση δεδομένων" (στην πραγματικότητα είναι απλώς ένα Dict). Βεβαιώσου ότι η συνάρτηση επιστρέφει Err(UserNotFound(user_id)) σε περίπτωση που ο χρήστης δεν βρεθεί, αντί για Err(KeyNotFound).
  2. Υλοποίησε τη parse_user_id ώστε να μετατρέπει τη διαδρομή του URL (όπως "/users/123") σε θετικό ακέραιο αναγνωριστικό χρήστη (123). Σε περίπτωση σφάλματος, επίστρεψε Err(InvalidUserId(user_id_str)).
  3. Υλοποίησε τη getPage:
    • Αν το URL είναι "https://example.com/", επίστρεψε Ok("Home page")
    • Αν το URL είναι "https://example.com/users/", επίστρεψε Ok("Users page")
    • Αν το URL είναι "https://example.com/users/<user_id>", ανάλυσε το αναγνωριστικό χρήστη, φόρτωσε τον χρήστη με αυτό το αναγνωριστικό και επίστρεψε Ok("<user name>'s page")
    • Αν το πρόθεμα του URL δεν είναι "https://", επίστρεψε Err(InsecureConnection(url))
    • Αν το όνομα τομέα του URL δεν είναι "example.com", επίστρεψε Err(InvalidDomain(url))
    • Αν η διαδρομή δεν είναι / ή /users/ ή /users/<user id>, επίστρεψε Err(PageNotFound(path))
    • Αν το αναγνωριστικό χρήστη δεν είναι θετικός ακέραιος, επίστρεψε Err(InvalidUserId(user_id_str))
    • Αν ο χρήστης δεν υπάρχει, επίστρεψε Err(UserNotFound(user_id))
  4. Υλοποίησε τη error_essage ώστε να μετατρέπει τα προηγούμενα σφάλματα σε μεταφρασμένα μηνύματα σφάλματος. Η συνάρτηση θα πρέπει τουλάχιστον να χειρίζεται τα αγγλικά, αλλά σε ενθαρρύνουμε να δοκιμάσεις να χειριστείς και κάποια άλλη γλώσσα. Τα αγγλικά μηνύματα σφάλματος θα πρέπει να μοιάζουν κάπως έτσι:
  • "Insecure connection (non HTTPS): http://example.com/users/789"
  • "Invalid domain name: https://google.com/wrong"
  • "Page not found: /oops"
  • "User ID is not a positive integer: abc"
  • "User #42 was not found"

Σημείωση: αντί να εμφανίζεις ένα μήνυμα σφάλματος στον χρήστη όταν χρησιμοποιεί HTTP αντί για HTTPS, ο διακομιστής ιστού σου θα μπορούσε να ανακατευθύνει το πρόγραμμα περιήγησής του στο HTTPS, και ο χρήστης δε θα παρατηρούσε καν το σφάλμα. Εφόσον τα σφάλματα στη Roc είναι φιλικά προς τη μηχανή, αυτό θα ήταν πολύ εύκολο να υλοποιηθεί.

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

Έτοιμος να ξεκινήσεις την άσκηση Διαχείριση Σφαλμάτων;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Roc με 126 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.