Implementa distintos tipos de manejo de errores y de gestión de recursos.
Un punto importante de la programación es cómo manejar los errores y cerrar los recursos incluso si se producen errores.
Este ejercicio requiere que manejes varios errores. Como el manejo de errores es bastante específico de cada lenguaje de programación, tendrás que consultar los tests de tu track para ver exactamente qué se requiere.
Estás construyendo un pequeño servidor web que consulta una base de datos de usuarios aún más pequeña. Suena fácil, pero en el mundo real muchas cosas pueden salir mal (y a menudo salen mal):
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" y "https://example.com/users/<user_id>"
user_id no sea un entero positivouser_id
Cuando algo sale mal, es importante darle al usuario final un mensaje de error agradable y útil para que pueda resolver el problema. Para esto, debes asegurarte de que tu código propague errores informativos desde el punto donde se detecta el error hasta el punto donde se produce el mensaje de error.
Por suerte, Roc te permite llevar un payload (es decir, datos) dentro de tu etiqueta Err. Es tentador llevar un mensaje de error directamente (por ejemplo, Err("User #42 was not found")), y puede que eso esté bien en algunos casos simples, pero tiene varias limitaciones:
Str.to_u64 se puede usar para parsear todo tipo de enteros: días, segundos, IDs de usuario y 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 cambio una etiqueta significativa junto con su propio payload útil. Por ejemplo, si no se encuentra el usuario, el error se verá como Err(UserNotFound(42)).
¡Muy bien, empecemos! Esto es lo que tienes que hacer:
get_user para devolver el usuario solicitado desde la "base de datos" users (en realidad solo es un Dict). Asegúrate de que la función devuelva Err(UserNotFound(user_id)) en caso de que 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 ID 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>", parsea el ID de usuario, carga el usuario con ese ID 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 debe manejar al menos el inglés, pero te animamos a intentar manejar otro idioma también. Los mensajes de error en inglés deberían verse 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 mostrarle 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 los errores son amigables para la máquina en Roc, 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.