Implementa diverse forme di gestione degli errori e delle risorse.
Un punto importante della programmazione è come gestire gli errori e chiudere le risorse anche quando si verificano degli errori.
Questo esercizio ti chiede di gestire vari errori. Dato che la gestione degli errori dipende parecchio dal linguaggio di programmazione, dovrai consultare i test del tuo track per vedere esattamente cosa è richiesto.
Stai costruendo un piccolo web server che interroga un database di utenti ancora più piccolo. Sembra facile, ma nel mondo reale molte cose possono (e spesso lo fanno) andare storte:
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" e "https://example.com/users/<user_id>"
user_id potrebbe non essere un numero intero positivouser_id
Quando qualcosa va storto, è importante dare all'utente finale un messaggio di errore chiaro e utile, così che possa risolvere il problema. Per farlo, devi assicurarti che il codice propaghi errori informativi dal punto in cui l'errore viene rilevato al punto in cui viene prodotto il messaggio di errore.
Per fortuna, Roc ti permette di trasportare un payload (cioè dei dati) all'interno del tag Err. È tentante trasportare direttamente un messaggio di errore (ad esempio, Err("User #42 was not found")), ed in alcuni casi semplici può andare bene, ma questo approccio ha diversi limiti:
Str.to_u64 può essere usata per interpretare ogni genere di numero intero: giorni, secondi, ID utente e altro ancora. Se il messaggio di errore dice solo Could not convert string "0.5" to a positive integer, l'utente potrebbe non avere abbastanza contesto per risolvere il problema.Quindi in questo esercizio, gli errori trasporteranno invece un tag significativo insieme al suo payload utile. Per esempio, se l'utente non viene trovato, l'errore sarà simile a Err(UserNotFound(42)).
Bene, iniziamo! Ecco cosa devi fare:
get_user in modo che restituisca l'utente richiesto dal «database» users (in realtà è solo un Dict). Assicurati che la funzione restituisca Err(UserNotFound(user_id)) se l'utente non viene trovato, invece di Err(KeyNotFound).parse_user_id per convertire il percorso dell'URL (come "/users/123") in un ID utente intero positivo (123). In caso di errore, restituisci Err(InvalidUserId(user_id_str)).getPage:
"https://example.com/", restituisci Ok("Home page")
"https://example.com/users/", restituisci Ok("Users page")
"https://example.com/users/<user_id>", interpreta l'ID utente, carica l'utente con quell'ID e restituisci Ok("<user name>'s page")
"https://", restituisci Err(InsecureConnection(url))
"example.com", restituisci Err(InvalidDomain(url))
/ o /users/ o /users/<user id>, restituisci Err(PageNotFound(path))
Err(InvalidUserId(user_id_str))
Err(UserNotFound(user_id))
error_essage per convertire gli errori precedenti in messaggi di errore tradotti. La funzione dovrebbe gestire almeno l'inglese, ma ti incoraggiamo a provare a gestire anche un'altra lingua. I messaggi di errore in inglese dovrebbero essere così:"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"Nota: invece di mostrare un messaggio di errore all'utente quando usa HTTP al posto di HTTPS, il web server potrebbe reindirizzare il browser verso HTTPS, e l'utente non noterebbe nemmeno l'errore. Dato che in Roc gli errori sono comprensibili alla macchina, sarebbe molto facile da implementare.
Iscriviti a Exercism per imparare e padroneggiare Roc con 126 esercizi e il mentoring di persone reali, tutto gratis.