Question 1: Is this the right way to implement Custom Exceptions?
I have a class with custom exceptions that I want to throw in the exception handler:
status_codes.py
from enum import Enum
class StatusCodes(Enum):
"""
Subset of suitable HTTP status codes that are good fit to describe the scenario of the custom exceptions.
"""
NO_CONTENT = 204
BAD_REQUEST = 400
NOT_AUTHORIZED = 401
NOT_FOUND = 404
NOT_ACCEPTABLE = 406
REQUEST_TIMEOUT = 408
EXPECTATION_FAILED = 412
UNPROCESSABLE_ENTITY = 422
INTERNAL_SERVER_ERROR = 500
BAD_GATEWAY = 502
SERVICE_UNAVAILABLE = 503
GATEWAY_TIMEOUT = 504
So I created a custom exception handler with the status_name
as a parameter:
from fastapi import FastAPI, Request
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from status_codes import StatusCodes
app = FastAPI()
class CustomException(Exception):
def __init__(self, status_name: str):
self.status_name = status_name
self.status_code = status_name.value()
def check_if_exception_exists(self):
# TODO
@app.exception_handler(CustomException)
async def validation_exception_handler(request: Request, exc: CustomException):
return JSONResponse(
status_code=exc.status_code,
content=jsonable_encoder({exc.status_code: exc.status_name}),
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise CustomException(status_name=StatusCodes.NOT_ACCEPTABLE)
return {"unicorn_name": name}
In the end it should look like this (I hardcoded the response for demonstration purposes):
Question 2: Why is my approach not working?
I don't want to pass two parameters, because status_code.py
contains all information already:
Example of: I pass the status_code and the status_name as a parameter:
from fastapi import FastAPI, Request
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from status_codes import StatusCodes
app = FastAPI()
class CustomException(Exception):
def __init__(self, status_name: str, status_code: int):
self.status_name = status_name
self.status_code = status_code
@app.exception_handler(CustomException)
async def validation_exception_handler(request: Request, exc: CustomException):
return JSONResponse(
status_code=exc.status_code,
content=jsonable_encoder({exc.status_code: exc.status_name}),
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise CustomException(status_name=StatusCodes.NOT_ACCEPTABLE, status_code=StatusCodes.NOT_ACCEPTABLE.value)
return {"unicorn_name": name}
This is the output of the code above (Why is the output "status_code" : "status_code" and not "status_code" : "status_name"?)