Médio Go
Erro customizado com código de status
Enunciado
Crie um tipo HTTPError que implementa error e contém os campos Status int e Message string. A função requisitar(url string) error retorna um *HTTPError com status 404 se a URL for "/nao-existe". No main, use errors.As para extrair o *HTTPError e imprimir o status e a mensagem.
Requisitos
- Definir a struct
HTTPErrorcom camposStatuseMessage. - Implementar o método
Error() stringpara*HTTPError. - A função
requisitarretorna*HTTPErrorcom status 404 para a URL específica. - No
main, usarerrors.Aspara obter o erro customizado e imprimirStatuseMessage.
Código inicial
package main
import (
"errors"
"fmt"
)
// Defina HTTPError
func requisitar(url string) error {
// Implemente
return nil
}
func main() {
// Chame requisitar("/nao-existe") e trate o erro
}
Saída esperada
Status: 404, Mensagem: não encontrado
Ver dica
O método Error() deve retornar uma string formatada. Use errors.As para converter o erro para *HTTPError.
Mostrar solução
package main
import (
"errors"
"fmt"
)
type HTTPError struct {
Status int
Message string
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTP %d: %s", e.Status, e.Message)
}
func requisitar(url string) error {
if url == "/nao-existe" {
return &HTTPError{Status: 404, Message: "não encontrado"}
}
return nil
}
func main() {
err := requisitar("/nao-existe")
var httpErr *HTTPError
if errors.As(err, &httpErr) {
fmt.Printf("Status: %d, Mensagem: %s\n", httpErr.Status, httpErr.Message)
}
}
Passo a passo
- Definimos a struct
HTTPErrorcom os camposStatuseMessage. - Implementamos o método
Error() stringno ponteiro*HTTPError, formatando a mensagem. - A função
requisitarverifica a URL e retorna um*HTTPErrorcom status 404 para/nao-existe. - No
main, chamamosrequisitare armazenamos o erro. - Declaramos uma variável
httpErrdo tipo*HTTPErrore usamoserrors.Aspara tentar converter o erro para esse tipo. - Se a conversão for bem-sucedida, imprimimos os campos.
Por que funciona
Erros customizados permitem carregar dados estruturados. errors.As percorre a cadeia de erros (incluindo erros envolvidos) e verifica se algum deles é do tipo alvo, preenchendo a variável com o valor encontrado.
Erros comuns
- Implementar
Error()no valor e não no ponteiro: seError()for definido emHTTPError(valor), então*HTTPErrortambém implementaerror, maserrors.Ascom*HTTPErrorpode não funcionar como esperado. Prefira definir no ponteiro. - Usar
errors.Isem vez deerrors.As:errors.Iscompara valores, não tipos. Para extrair dados, useerrors.As. - Esquecer de passar o endereço para
errors.As: o segundo argumento deve ser um ponteiro para a variável que receberá o erro.
Outra forma de resolver
Poderia usar uma asserção de tipo direta: if e, ok := err.(*HTTPError); ok { ... }. Mas isso não funciona se o erro estiver envolvido com %w. errors.As é mais robusto.
Saída esperada
Status: 404, Mensagem: não encontrado