5

I'm currently writing a few end points for an API in fastAPI. I'm defining classes that extend fastapi's HTTPException.

The problem is that HTTPException returns a response body with an attribute called detail which will either be a string or a json structure depending on what object you pass to it as seem below.

{
  "detail": {
    "msg": "error message here"
  }
}


{   "detail": "error message here" }

I would like to override this behavior and let it respond with my own structure.

I'm aware that i can install custom exceptions using the exception handler decorator and have that return a JSONResponse object but this is not what i'm looking for.

Chris
  • 18,724
  • 6
  • 46
  • 80
neo-devnull
  • 51
  • 1
  • 3
  • You can simply return a python dict. FastAPI will turn that into json automatically. – phyominh Feb 19 '21 at 07:25
  • @phyominh yes i am aware of this however the reason i want to go down this path is to implement a sort of standard into the api, that all errors will be exceptions, can be raised and caught – neo-devnull Feb 19 '21 at 07:39
  • 1
    Can this https://fastapi.tiangolo.com/tutorial/handling-errors/ help? – lsabi Feb 19 '21 at 08:31
  • Did you manage to solve this? I want to do something similar and any hint would be appreciated. Thank you in advance and regards – Javier Guzmán Mar 22 '23 at 15:29
  • You might find [this answer](https://stackoverflow.com/a/71682274/17865804), as well as [this](https://stackoverflow.com/a/72833284/17865804) and [this](https://stackoverflow.com/a/71800464/17865804) helpful – Chris May 15 '23 at 16:53

1 Answers1

2

One option is to set the status code corresponding to your exception, and then return a custom response body.

Here is a simple toy example using this approach to workaround the issue at hand:

from fastapi import FastAPI, Response, status

myapp = FastAPI()

@myapp.get("/")
async def app_func(response: Response, myparam: str):

    #end point code here

    valid_params = ['a', 'b', 'c']
    
    if myparam not in valid_params:
        #Customize logic, status code, and returned dict as needed

        response.status_code = status.HTTP_400_BAD_REQUEST

        return {'message': 'Oh no! I failed (without detail key)'}

    
    response.status_code = status.HTTP_200_OK
    return {'message': 'Yay! I succeeded!'}      

A full list of available status codes can be found here.

jaredbgo
  • 21
  • 3