Capítulo 3.6: Tratamento de Erros e Validação
Tempo de estudo: 50 minutos
1. Tratamento de Erros: "Escudos de Emergência" da Nave Espacial
Mesmo na nave mais perfeita, situações imprevistas podem ocorrer:
- Comando incorreto do Centro de Controle da Missão (CCM): O cliente enviou dados incorretos.
- Perda de comunicação com o módulo: Recurso não encontrado no banco de dados.
- Falha no reator: Erro interno do servidor.
O tratamento adequado de erros é um sistema de "escudos de emergência". Ele impede que a nave se desintegre e, em vez disso, envia um sinal claro ao CCM sobre o que deu errado.
💡 Analogia espacial:
Em vez de simplesmente transmitir um sinal de "AVARIA!" ao CCM, um bom computador de bordo enviará um relatório estruturado:
Isso permite que os engenheiros na Terra entendam rapidamente o problema e tomem medidas.
2. Validação Pydantic: O "Computador de Bordo" Integrado
Já encontramos a magia do Pydantic. Se você tentar criar uma nave com um tipo de dado inválido (por exemplo, launch_year
como uma string), o FastAPI retornará automaticamente um erro 422 Unprocessable Entity
com uma descrição detalhada de qual campo e por que a validação falhou.
Exemplo de requisição para POST /spaceships
:
{
"name": "X-Wing",
"type": "Caça",
"launch_year": "há muito tempo", // <-- Tipo inválido!
"status": "Em operação"
}
Resposta automática do FastAPI:
{
"detail": [
{
"loc": [
"body",
"launch_year"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
3. Tratamento de "Recurso não Encontrado": Exceção HTTPException
Já usamos isso em operações CRUD. HTTPException
é a maneira padrão do FastAPI de interromper a execução de uma requisição e retornar imediatamente uma resposta de erro ao cliente.
Vamos relembrar o código de GET /spaceships/{ship_id}
:
# main.py
from fastapi import FastAPI, HTTPException # Certifique-se de que HTTPException esteja importado
# ...
@app.get("/spaceships/{ship_id}", response_model=Spaceship, tags=["Naves Espaciais"])
def get_spaceship(ship_id: int):
ship = db_spaceships.get(ship_id)
if not ship:
# Se a nave não for encontrada, "lançamos" a exceção 404
raise HTTPException(status_code=404, detail=f"Nave espacial com ID {ship_id} não encontrada")
return ship
raise HTTPException(...)
: Esta chamada interrompe a execução da função.status_code=404
: Define o status HTTP da resposta.detail
: Mensagem que será enviada ao cliente no corpo da resposta JSON.
4. Validadores Personalizados: "Verificações Especiais" antes do Lançamento
E se quisermos adicionar nossa própria lógica de negócio, mais complexa? Por exemplo, proibir o lançamento de naves com o nome "Estrela da Morte".
Para isso, o Pydantic oferece uma ferramenta poderosa — validadores.
Passo 1: Adicionar o validador ao modelo SpaceshipCreate
# main.py
from pydantic import BaseModel, Field, validator
class SpaceshipCreate(BaseModel):
name: str = Field(..., min_length=3, max_length=50)
type: str
launch_year: int = Field(..., gt=1950)
status: str
@validator('name')
def name_must_not_be_forbidden(cls, v):
"""Verifica se o nome da nave não está na lista de proibidos."""
if 'Death Star' in v:
raise ValueError('Nomes como "Estrela da Morte" são proibidos por decreto Imperial!')
return v.title() # De quebra, convertemos o nome para maiúsculas
@validator('name')
: Decorador que "vincula" esta função ao camponame
.cls, v
: O método recebe a própria classe (cls
) e o valor do campo (v
).raise ValueError(...)
: Se a verificação falhar, levantamos uma exceção Python padrão. O FastAPI a interceptará e a transformará em um belo erro422
.return v.title()
: Se tudo estiver bem, devemos obrigatoriamente retornar o valor. Podemos até modificá-lo em tempo real (por exemplo, padronizá-lo).
Passo 2: Testar
Reinicie o uvicorn
e tente criar uma nave com um nome proibido via /docs
. Você receberá um erro 422
com sua mensagem personalizada!
5. Tratamento Global de Erros: "Protocolo de Emergência" da Estação
Às vezes, é necessário interceptar erros inesperados (por exemplo, falha na conexão com um banco de dados real) e retornar um formato de resposta unificado e padronizado.
Para isso, o decorador @app.exception_handler
é utilizado.
Exemplo: Interceptação de todos os erros ValueError
# main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
# ...
@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
"""
Manipulador global para todos os erros ValueError,
para retornar JSON padronizado.
"""
return JSONResponse(
status_code=400,
content={"message": f"Erro nos dados: {str(exc)}"},
)
@app.exception_handler(ValueError)
: Informa ao FastAPI que esta função deve lidar com todos osValueError
que não foram interceptados anteriormente.async def ...
: Manipuladores de exceção devem ser assíncronos (async
).JSONResponse
: Permite controle total sobre o corpo e o status da resposta.
Agora, quando nosso validador personalizado for acionado, a resposta terá um formato mais amigável que definimos.
Quiz para fixação
🚀 Resumo do Capítulo:
Você instalou em sua nave API um poderoso sistema de proteção e protocolos de emergência. Agora ela é capaz de:
- 🛡️ Rejeitar automaticamente ataques de "dados inválidos" usando Pydantic.
- 🚨 Notificar corretamente a ausência de recursos (
404 Not Found
) através deHTTPException
. - ⚙️ Realizar "verificações especiais" com validadores personalizados.
- 🧯 Interceptar globalmente falhas inesperadas e fornecer respostas padronizadas.
Seu "hipermotor" não é apenas rápido, mas também incrivelmente confiável!
📌 Verificação:
- Tente criar uma nave com o nome "Death Star" e verifique se você recebe um erro
400
com sua mensagem personalizada.- Tente solicitar
GET /spaceships/999
e verifique se você recebe um erro404
.- Tente enviar uma solicitação
POST
comlaunch_year
como uma string e verifique se você recebe um erro422
.⚠️ Se houver erros:
- Certifique-se de que todos os módulos necessários (
HTTPException
,validator
,Request
,JSONResponse
) foram importados.- Verifique se os decoradores
@validator
e@app.exception_handler
foram escritos sem erros de digitação.
Parabéns por completar o Capítulo 3! Você construiu e lançou do zero uma API poderosa, documentada e segura com FastAPI. Você está pronto para realizar missões espaciais reais