Tracks
/
Roc
Roc
/
Ejercicios
/
Manejo de errores
Manejo de errores

Manejo de errores

Intermedia

Instrucciones

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.

Implementación

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

  • la conexión puede ser insegura: la URL debe empezar con "https://"
  • el nombre de dominio puede ser inválido: en este ejercicio, debe ser "example.com"
  • puede que la página no se encuentre: 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 entero positivo
  • puede que no exista ningún usuario en la base de datos con ese user_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:

  • puede que no tengas suficiente contexto dentro de la función que detecta el error para producir un mensaje de error lo bastante útil.
    • Por ejemplo, la función 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.
  • 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 payloads de tipo string, tu código de manejo de errores tendrá que parsear ese string para saber qué problema ocurrió: esto es ineficiente y puede romperse con facilidad si alguna vez se modifica el mensaje de error.
  • si tu sitio web es multilingüe, tendrás que traducir el mensaje de error al idioma del usuario. Va a ser mucho más fácil hacerlo si el payload del error son datos amigables para la máquina en lugar de un string en inglés.

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:

  1. Implementa 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).
  2. Implementa 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)).
  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>", parsea el ID de usuario, carga el usuario con ese ID 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 ID de usuario no es un 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 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.

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

¿Todo listo para empezar Manejo de errores?

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