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.
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):
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" e "https://example.com/users/<user_id>" são permitidasuser_id pode não ser um inteiro positivouser_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:
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.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:
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).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)).getPage:
"https://example.com/", retorne Ok("Home page")
"https://example.com/users/", retorne Ok("Users page")
"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")
"https://", retorne Err(InsecureConnection(url))
"example.com", retorne Err(InvalidDomain(url))
/, nem /users/, nem /users/<user id>, retorne Err(PageNotFound(path))
Err(InvalidUserId(user_id_str))
Err(UserNotFound(user_id))
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.
Crie sua conta no Exercism para aprender e dominar Roc com 126 exercícios e mentoria humana de verdade, tudo de graça.