Implémente différentes formes de gestion des erreurs et des ressources.
Un aspect important de la programmation consiste à gérer les erreurs et à fermer les ressources même lorsque des erreurs se produisent.
Cet exercice te demande de gérer différents types d'erreurs. Comme la gestion des erreurs est plutôt spécifique au langage de programmation, tu devras consulter les tests de ton parcours pour voir ce qui est exactement attendu.
Tu construis un tout petit serveur web qui interroge une base de données d'utilisateurs encore plus petite. Ça a l'air simple, mais dans le monde réel, beaucoup de choses peuvent mal tourner (et c'est souvent le cas) :
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" et "https://example.com/users/<user_id>" sont autoriséesuser_id n'est peut-être pas un entier positifuser_id dans la base de donnéesQuand quelque chose tourne mal, il est important de présenter à l'utilisateur final un message d'erreur clair et utile pour qu'il puisse résoudre le problème. Pour cela, ton code doit faire remonter des erreurs informatives depuis l'endroit où l'erreur est détectée jusqu'à l'endroit où le message d'erreur est produit.
Heureusement, Roc te permet de transporter une charge utile (c'est-à-dire des données) à l'intérieur de ton tag Err. Il est tentant de transporter directement un message d'erreur (par exemple Err("User #42 was not found")), et ça peut convenir dans certains cas simples, mais cette approche a plusieurs limites :
Str.to_u64 peut servir à analyser toutes sortes d'entiers : des jours, des secondes, des identifiants d'utilisateur, et bien d'autres. Si le message d'erreur dit simplement Could not convert string "0.5" to a positive integer, l'utilisateur n'a peut-être pas assez de contexte pour résoudre le problème.Dans cet exercice, tes erreurs transporteront donc un tag explicite accompagné de sa propre charge utile. Par exemple, si l'utilisateur n'est pas trouvé, l'erreur ressemblera à Err(UserNotFound(42)).
Bon, c'est parti ! Voici ce que tu dois faire :
get_user pour renvoyer l'utilisateur demandé depuis la « base de données » users (en réalité, ce n'est qu'un Dict). Vérifie que la fonction renvoie Err(UserNotFound(user_id)) quand l'utilisateur n'est pas trouvé, et non Err(KeyNotFound).parse_user_id pour convertir le chemin de l'URL (par exemple "/users/123") en un identifiant d'utilisateur entier positif (123). En cas d'erreur, renvoie Err(InvalidUserId(user_id_str)).getPage :
"https://example.com/", renvoie Ok("Home page")
"https://example.com/users/", renvoie Ok("Users page")
"https://example.com/users/<user_id>", analyse l'identifiant d'utilisateur, charge l'utilisateur correspondant et renvoie Ok("<user name>'s page")
"https://", renvoie Err(InsecureConnection(url))
"example.com", renvoie Err(InvalidDomain(url))
/, /users/ ou /users/<user id>, renvoie Err(PageNotFound(path))
Err(InvalidUserId(user_id_str))
Err(UserNotFound(user_id))
error_essage pour convertir les erreurs précédentes en messages d'erreur traduits. La fonction doit au minimum gérer l'anglais, mais on t'encourage à essayer de gérer aussi une autre langue. Les messages d'erreur en anglais devraient ressembler à ceci :"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"Remarque : au lieu d'afficher un message d'erreur à l'utilisateur qui utilise HTTP au lieu de HTTPS, ton serveur web pourrait rediriger son navigateur vers HTTPS, et l'utilisateur ne remarquerait même pas l'erreur. Comme les erreurs sont exploitables par une machine en Roc, ce serait très facile à implémenter.
Inscris-toi sur Exercism pour apprendre et maîtriser Roc avec 126 exercices, et un vrai mentorat humain, le tout gratuitement.