Rutas
/
Roc
Roc
/
Ejercicios
/
Gestión de errores
Gestión de errores

Gestión de errores

Media

Instrucciones

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.

Implementación

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):

  • la conexión puede no ser segura: la URL debe empezar por "https://"
  • el nombre de dominio puede no ser válido: en este ejercicio, debe ser "example.com"
  • puede que no se encuentre la página: solo se permiten "https://example.com/", "https://example.com/users/" y "https://example.com/users/<user_id>"
  • puede que el user_id no sea un número entero positivo
  • puede que no exista ningún usuario en la base de datos con este user_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:

  • puede que no tengas suficiente contexto dentro de la función que detecta el error como para producir un mensaje de error lo bastante útil.
    • Por ejemplo, la función 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.
  • en muchos casos, tu código de manejo de errores puede necesitar tratar algunos errores de forma distinta a otros. Sin embargo, si los errores solo llevan cargas útiles de tipo string, tu código de manejo de errores tendrá que analizar ese string para saber qué problema ha ocurrido: esto es ineficiente y puede romperse con facilidad si alguna vez se retoca el mensaje de error.
  • si tu sitio web es multilingüe, tendrás que traducir el mensaje de error al idioma del usuario. Eso será mucho más fácil si la carga útil del error son datos aptos para máquinas en lugar de un string en inglés.

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:

  1. Implementa 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).
  2. Implementa 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)).
  3. Implementa getPage:
    • Si la URL es "https://example.com/", devuelve Ok("Home page")
    • Si la URL es "https://example.com/users/", devuelve Ok("Users page")
    • Si la URL es "https://example.com/users/<user_id>", analiza el identificador de usuario, carga el usuario con ese identificador y devuelve Ok("<user name>'s page")
    • Si el prefijo de la URL no es "https://", devuelve Err(InsecureConnection(url))
    • Si el nombre de dominio de la URL no es "example.com", devuelve Err(InvalidDomain(url))
    • Si la ruta no es /, /users/ o /users/<user id>, devuelve Err(PageNotFound(path))
    • Si el identificador de usuario no es un número entero positivo, devuelve Err(InvalidUserId(user_id_str))
    • Si el usuario no existe, devuelve Err(UserNotFound(user_id))
  4. Implementa 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.

Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Roc Exercism

¿Listo para empezar Gestión de errores?

Regístrate en Exercism para aprender y dominar Roc con 126 ejercicios y mentoría humana real, todo gratis.