Trilhas
/
Roc
Roc
/
Exercícios
/
Tratamento de erros
Tratamento de erros

Tratamento de erros

Médio

Instruções

Implemente vários tipos de tratamento de erros e de gerenciamento de recursos.

Um ponto importante da programação é saber como tratar erros e fechar recursos mesmo quando ocorrem erros.

Este exercício pede que você trate vários erros. Como o tratamento de erros é bastante específico de cada linguagem de programação, você vai precisar consultar os testes da sua trilha para ver exatamente o que é necessário.

Implementação

Você está construindo um pequeno servidor web que consulta um banco de dados de usuários ainda menor. Parece fácil, mas no mundo real muitas coisas podem dar errado (e muitas vezes dão):

  • a conexão pode ser insegura: a URL precisa começar com "https://"
  • o nome de domínio pode ser inválido: neste exercício, ele deve ser "example.com"
  • a página pode não ser encontrada: apenas "https://example.com/", "https://example.com/users/" e "https://example.com/users/<user_id>" são permitidas
  • o user_id pode não ser um inteiro positivo
  • pode não existir nenhum usuário no banco de dados com esse user_id

Quando algo dá errado, é importante dar ao usuário final uma mensagem de erro clara e útil, para que ele consiga resolver o problema. Para isso, você precisa garantir que seu código propague erros informativos do ponto onde o erro é detectado até o ponto onde a mensagem de erro é produzida.

Felizmente, Roc permite carregar um payload (ou seja, dados) dentro da sua tag Err. É tentador carregar uma mensagem de erro diretamente (por exemplo, Err("User #42 was not found")), e isso pode funcionar em alguns casos simples, mas tem várias limitações:

  • talvez você não tenha contexto suficiente dentro da função que detecta o erro para produzir uma mensagem de erro realmente útil.
    • Por exemplo, a função Str.to_u64 pode ser usada para interpretar todo tipo de inteiro: dias, segundos, IDs de usuário e muito mais. Se a mensagem de erro disser apenas Could not convert string "0.5" to a positive integer, o usuário pode não ter contexto suficiente para resolver o problema.
  • em muitos casos, seu código de tratamento de erros pode precisar tratar alguns erros de forma diferente de outros. Porém, se os erros carregarem apenas strings, seu código de tratamento de erros vai ter que interpretar essa string para saber qual problema ocorreu: isso é ineficiente e pode quebrar facilmente se a mensagem de erro for alterada.
  • se o seu site for multilíngue, você vai precisar traduzir a mensagem de erro para o idioma do usuário. Isso vai ser muito mais fácil se o payload do erro for um dado amigável para máquinas, em vez de uma string em inglês.

Então, neste exercício, seus erros vão carregar uma tag significativa junto com seu próprio payload útil. Por exemplo, se o usuário não for encontrado, o erro vai ficar assim: Err(UserNotFound(42)).

Certo, vamos começar! Aqui está o que você precisa fazer:

  1. Implemente get_user para retornar o usuário solicitado do users "banco de dados" (na verdade, é só um Dict). Garanta que a função retorne Err(UserNotFound(user_id)) caso o usuário não seja encontrado, em vez de Err(KeyNotFound).
  2. Implemente parse_user_id para converter o caminho da URL (como "/users/123") em um ID de usuário inteiro positivo (123). Em caso de erro, retorne Err(InvalidUserId(user_id_str)).
  3. Implemente getPage:
    • Se a URL for "https://example.com/", retorne Ok("Home page")
    • Se a URL for "https://example.com/users/", retorne Ok("Users page")
    • Se a URL for "https://example.com/users/<user_id>", interprete o ID do usuário, carregue o usuário com esse ID e retorne Ok("<user name>'s page")
    • Se o prefixo da URL não for "https://", retorne Err(InsecureConnection(url))
    • Se o nome de domínio da URL não for "example.com", retorne Err(InvalidDomain(url))
    • Se o caminho não for /, nem /users/, nem /users/<user id>, retorne Err(PageNotFound(path))
    • Se o ID do usuário não for um inteiro positivo, retorne Err(InvalidUserId(user_id_str))
    • Se o usuário não existir, retorne Err(UserNotFound(user_id))
  4. Implemente error_essage para converter os erros anteriores em mensagens de erro traduzidas. A função deve pelo menos lidar com inglês, mas recomendamos que você tente lidar também com outro idioma. As mensagens de erro em inglês devem ficar assim:
  • "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"

Observação: em vez de mostrar uma mensagem de erro ao usuário quando ele usa HTTP em lugar de HTTPS, seu servidor web poderia redirecionar o navegador dele para HTTPS, e o usuário nem notaria o erro. Como os erros são amigáveis para máquinas em Roc, isso seria muito fácil de implementar.

Editar via GitHub O link abre em uma nova janela ou aba
Roc Exercism

Tudo pronto para começar Tratamento de erros?

Crie sua conta no Exercism para aprender e dominar Roc com 126 exercícios e mentoria humana de verdade, tudo de graça.