Excepções & Exception Handlers¶
Exception handlers são, como o nome sugere, as funções que lidam com excepções do tipo X caso ocorram.
Exception handlers¶
Em cada nível o parâmetro exception_handler
(entre outros) está disponível para ser utilizado e pronto a lidar com
excepções espeíficas para cada nível.
As exception handlers são declaras num dicionário python e pode passar como chave a excepção em si ou o status_code
que vai sempre utilizar a excepção em si.
from json import loads
from lilya import status
from lilya.apps import Lilya
from lilya.requests import Request
from lilya.responses import JSONResponse
from lilya.routing import Include, Path
async def handle_type_error(request: Request, exc: TypeError):
status_code = status.HTTP_400_BAD_REQUEST
details = loads(exc.json()) if hasattr(exc, "json") else exc.args[0]
return JSONResponse({"detail": details}, status_code=status_code)
async def handle_value_error(request: Request, exc: ValueError):
status_code = status.HTTP_400_BAD_REQUEST
details = loads(exc.json()) if hasattr(exc, "json") else exc.args[0]
return JSONResponse({"detail": details}, status_code=status_code)
async def me():
return "Hello, world!"
app = Lilya(
routes=[
Include(
"/",
routes=[
Path(
"/me",
handler=me,
)
],
)
],
exception_handlers={
TypeError: handle_type_error,
ValueError: handle_value_error,
},
)
O que está a acontecer¶
O nível da aplicação contém um manipulador de excepções handle_type_error
e handle_value_error e isso significa que para
toda HTTPException
e ValueError
lançada na aplicação, será tratada por essa função.
Exception handlers personalisadas¶
Todos sabemos que Lilya lida muito bem com excepções por design, mas às vezes também podemos
querer lançar um erro ao fazer alguma lógica de código que não está diretamente relacionada com um data
de
um exception handler.
Examplo
from lilya.apps import Lilya
from lilya.requests import Request
from lilya.routing import Path
async def create(request: Request):
data = await request.json()
if len(data) == 0:
raise ValueError("Cannot be 0.")
app = Lilya(
routes=[
Path(
"/create",
handler=create,
methods=["POST"],
)
],
)
Este exemplo não é nada comum, mas serve para mostrar onde uma excepção é lançada.
Lilya oferece um exception handler personalizado pronto a usar:
- handle_value_error - Quando se quer que a excepção
ValueError
seja automaticamente convertida num JSON.
from lilya._internal._exception_handlers import handle_value_error
Como ficaria o exemplo anterior utilizando este exception handler personalizado?
from lilya._internal._exception_handlers import handle_value_error
from lilya.apps import Lilya
from lilya.requests import Request
from lilya.routing import Path
async def create(request: Request):
data = await request.json()
if len(data) == 0:
raise ValueError("Cannot be 0.")
app = Lilya(
routes=[Path("/create", handler=create)],
exception_handlers={
ValueError: handle_value_error,
},
)
Uso dos status codes¶
Ao declarar exception handlers, como mencionado anteriormente, pode-se usar status codes em vez da
própria excepção. Isto permite e indica como uma excepção deve ser tratada quando ocorre um status_code
específico.
Isto pode ser muito útil se apenas se quiser restringir à abordagem do status_code
em vez da
própria Exception
.
from lilya.apps import Lilya
from lilya.exceptions import HTTPException
from lilya.requests import Request
from lilya.responses import Error
async def not_found(request: Request, exc: HTTPException):
return Error("Oops", status_code=exc.status_code)
async def server_error(request: Request, exc: HTTPException):
return Error("Oops", status_code=exc.status_code)
app = Lilya(
routes=...,
exception_handlers={
404: not_found,
500: server_error,
},
)
HTTPException¶
A classe HTTPException
serve como uma classe fundamental adequada para lidar com várias excepções.
Na implementação padrão do ExceptionMiddleware
, respostas HTTP no formato de texto simples são retornadas em qualquer instância de HTTPException
.
Note
O uso correto dita que se deve lançar o HTTPException
exclusivamente dentro de rotas ou endpoints.
Middleware e Permissões, por outro lado, devem simplesmente retornar as respostas apropriadas diretamente.
WebSocketException¶
A classe WebSocketException
é desenhada para lançar erros especificamente dentro de endpoints WebSocket.