Implementa distintas formas de gestión de errores y de recursos.
Un punto importante de la programación es saber cómo gestionar los errores y cerrar los recursos incluso cuando se producen errores.
Este ejercicio requiere que gestiones distintos tipos de errores. Como la gestión de errores depende bastante del lenguaje de programación, tendrás que consultar las pruebas de tu track para ver qué se necesita exactamente.
Vas a construir un pequeño servidor web que consulta una base de datos de usuarios aún más pequeña. Parece fácil, pero en el mundo real muchas cosas pueden salir mal (y a menudo lo hacen):
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" y "https://example.com/users/<user_id>"
user_id no sea un número entero positivouser_id
Cuando algo sale mal, es importante dar al usuario final un mensaje de error claro y útil para que pueda resolver el problema. Para ello, tienes que asegurarte de que tu código propague errores informativos desde el punto en el que se detecta el error hasta el punto en el que se produce el mensaje de error.
Por suerte, Roc te permite llevar una carga útil (es decir, datos) dentro de tu etiqueta Err. Es tentador llevar directamente un mensaje de error (por ejemplo, Err("User #42 was not found")), y puede que esté bien en algunos casos sencillos, pero tiene varias limitaciones:
Str.to_u64 sirve para analizar todo tipo de números enteros: días, segundos, identificadores de usuario y mucho más. Si el mensaje de error solo dice Could not convert string "0.5" to a positive integer, puede que el usuario no tenga suficiente contexto para resolver el problema.Así que, en este ejercicio, tus errores llevarán en su lugar una etiqueta significativa junto con su correspondiente carga útil informativa. Por ejemplo, si no se encuentra el usuario, el error tendrá este aspecto: Err(UserNotFound(42)).
¡Vale, empecemos! Esto es lo que tienes que hacer:
get_user para que devuelva el usuario solicitado desde la «base de datos» users (en realidad solo es un Dict). Asegúrate de que la función devuelve Err(UserNotFound(user_id)) cuando no se encuentre el usuario, en lugar de Err(KeyNotFound).parse_user_id para convertir la ruta de la URL (como "/users/123") en un identificador de usuario entero positivo (123). En caso de error, devuelve Err(InvalidUserId(user_id_str)).getPage:
"https://example.com/", devuelve Ok("Home page")
"https://example.com/users/", devuelve Ok("Users page")
"https://example.com/users/<user_id>", analiza el identificador de usuario, carga el usuario con ese identificador y devuelve Ok("<user name>'s page")
"https://", devuelve Err(InsecureConnection(url))
"example.com", devuelve Err(InvalidDomain(url))
/, /users/ o /users/<user id>, devuelve Err(PageNotFound(path))
Err(InvalidUserId(user_id_str))
Err(UserNotFound(user_id))
error_essage para convertir los errores anteriores en mensajes de error traducidos. La función debería manejar al menos el inglés, pero te animamos a que intentes manejar también otro idioma. Los mensajes de error en inglés deberían ser así:"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: en lugar de mostrar un mensaje de error al usuario cuando usa HTTP en vez de HTTPS, tu servidor web podría redirigir su navegador a HTTPS, y el usuario ni siquiera notaría el error. Como en Roc los errores son aptos para máquinas, esto sería muy fácil de implementar.
Regístrate en Exercism para aprender y dominar Roc con 126 ejercicios y mentoría humana real, todo gratis.