Implementa vários tipos de tratamento de erros e de gestão de recursos.
Um ponto importante da programação é saber tratar erros e fechar recursos mesmo quando ocorrem erros.
Este exercício pede que trates vários tipos de erros. Como o tratamento de erros depende bastante da linguagem de programação, tens de consultar os testes da tua track para veres exatamente o que é necessário.
Estás a construir um pequeno servidor web que consulta uma base de dados de utilizadores ainda mais pequena. Parece fácil, mas no mundo real muitas coisas podem correr mal (e muitas vezes correm):
"https://"
"example.com"
"https://example.com/", "https://example.com/users/" e "https://example.com/users/<user_id>"
user_id pode não ser um número inteiro positivouser_id
Quando algo corre mal, é importante dar ao utilizador final uma mensagem de erro agradável e útil, para que este possa resolver o problema. Para isso, tens de garantir que o teu código propaga erros informativos desde o ponto onde o erro é detetado até ao ponto onde a mensagem de erro é produzida.
Felizmente, o Roc permite-te transportar uma carga útil (ou seja, dados) dentro da tua etiqueta Err. É tentador transportar diretamente uma mensagem de erro (por exemplo, Err("User #42 was not found")), e isso pode ser aceitável em alguns casos simples, mas tem várias limitações:
Str.to_u64 pode ser usada para interpretar todo o tipo de números inteiros: dias, segundos, identificadores de utilizador e muito mais. Se a mensagem de erro disser apenas Could not convert string "0.5" to a positive integer, o utilizador pode não ter contexto suficiente para resolver o problema.Por isso, neste exercício, os teus erros vão antes transportar uma etiqueta com significado, acompanhada da sua própria carga útil informativa. Por exemplo, se o utilizador não for encontrado, o erro terá o aspeto Err(UserNotFound(42)).
Muito bem, vamos começar! Eis o que tens de fazer:
get_user para devolver o utilizador pedido a partir da "base de dados" users (na verdade, é apenas um Dict). Certifica-te de que a função devolve Err(UserNotFound(user_id)) caso o utilizador não seja encontrado, em vez de Err(KeyNotFound).parse_user_id para interpretar o caminho do URL (como "/users/123") e obter um identificador de utilizador inteiro positivo (123). Em caso de erro, devolve Err(InvalidUserId(user_id_str)).getPage:
"https://example.com/", devolve Ok("Home page")
"https://example.com/users/", devolve Ok("Users page")
"https://example.com/users/<user_id>", interpreta o identificador de utilizador, carrega o utilizador com esse identificador e devolve Ok("<user name>'s page")
"https://", devolve Err(InsecureConnection(url))
"example.com", devolve Err(InvalidDomain(url))
/, /users/ ou /users/<user id>, devolve 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, no mínimo, tratar inglês, mas és encorajado a tentar tratar também outra língua. As mensagens de erro em inglês devem ser 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"Nota: em vez de mostrar uma mensagem de erro ao utilizador quando este usa HTTP em vez de HTTPS, o teu servidor web podia redirecionar o navegador dele para HTTPS e o utilizador nem daria pelo erro. Como, em Roc, os erros são fáceis de interpretar por uma máquina, isto seria muito fácil de implementar.
Inscreve-te no Exercism para aprenderes e dominares Roc com 126 exercícios, e mentoria humana real, tudo grátis.