Package: ehandler
Exception Handler [ FastAPI Utility ]This project works together with FastAPI and allows you to create error handlers
in a very simple and standard way. Basically it allows you to add (or use the default
a function that will be executed when an exception occurs on the server.This is possible using the FastAPI Exception Handler (actually Starlette) and
using a function as a template that receives data such as the request object
that was invoked on the route, the exception, the status code that handles that
exception, and some'static'arguments.Table of ContentsHow to use itBasicExplanationExamplesContent callbackAdd additional dataChange default status codeContributePrerequisitesInstall PoetryInstall Pre-CommitInstall hooksInstall dependenciesAdd dependenciesAdd dev dependenciesRun testStatic testSingle testAll testAll filesStatic testHow to use itBasicThere are several ways to use it, the simplest is to use it with the templates
(Callbacks) that come by default. And simply create a list with the pairs of
exceptions and status codes.fromfastapiimportFastAPIfromehandlerimportExceptionHandlerSetterapp=FastAPI()handlers=[(ZeroDivisionError,500),(ValueError,400)]ExceptionHandlerSetter(content_callback_kwargs={"show_error":True,"show_data":True}).add_handlers(app,handlers)@app.get("/value_error")defraise_value_error():raiseValueError("Invalid value")@app.get("/division")defcall_external():returnsome_func()@app.get("/uncaught")defuncaught():raiseException("This error is not handled")defsome_func():print("Trying to do something unless that thing get fails")return1/0# This raise a `ZeroDivisionError`/value_error-HTTP 400 Bad Request{"detail":"Bad Request","error":"ValueError","message":"Invalid value"}/division-HTTP 500 Internal Server Error{"detail":"Internal Server Error","error":"ZeroDivisionError","message":"division by zero"}/uncaught-HTTP 500 Internal Server ErrorInternalServerErrorExplanationWhen an error occurs within our server that is not handled (with atry-except)
the server will respond with a500 - Internal Server ErrorExceptionHandlerSetter().add_handlers(app, handlers)Basically create this to
be able to handle specific exceptions (or general ifExceptionis handled)
(original example) :@app.exception_handler(UnicornException)asyncdefunicorn_exception_handler(request:Request,exc:UnicornException):returnJSONResponse(status_code=418,content={"message":f"Oops!{exc.name}did something. There goes a rainbow..."},)But with a dynamic/configurable exception and status code and using a function
(callback) as a template, in fact 2 functions/callbacks are used:One that parses the content, can take the exception, the request, etc, and
create some content with it.The other is the function that returns the response, usually just put it
inside aJSONResponse.@app.exception_handler(<ExceptionClass>)asyncdef<ResponseCallback>(request:Request,content:Any=<content_callback>,status_code:int=<status_code>)return<ContentCallback>,ExamplesContent callbackUse your own callback to parse the content of the responseimporttracebackfromfastapiimportFastAPIfromehandlerimportExceptionHandlerSetterapp=FastAPI()defparse_exception(request:Request,exception:Exception,status_code:int,debug:bool=False,)->dict:content={"message":"Something went wrong"}ifdebug:content["traceback"]=traceback.format_exc()returncontenthandlers=[(Exception,500)]ExceptionHandlerSetter(content_callback=parse_exceptioncontent_callback_kwargs={"debug":True}).add_handlers(app,handlers)Add additional data⚠️ This uses the default implementation fromehandler.parsers.parse_exceptionfromfastapiimportFastAPIfromehandlerimportExceptionHandlerSetterfromehandler.utilsimportadd_dataapp=FastAPI()handlers=[(Exception,500)]ExceptionHandlerSetter(content_callback_kwargs={"show_data":True}# If `show_data` is False it won't work).add_handlers(app,handlers)@app.get("/exception")defraise_value_error():raiseadd_data(ValueError("Invalid value"),{"user":"user_info"})/exception-HTTP 500 Internal Server Error{"data":{"user":"user_info"},"detail":"Internal Server Error","message":"Invalid value"}Change defaultstatus_codefromfastapiimportFastAPIfromehandlerimportExceptionHandlerSetterfromehandler.utilsimportadd_codeapp=FastAPI()handlers=[(Exception,500)]ExceptionHandlerSetter(force_status_code=False).add_handlers(app,handlers)@app.get("/exception")defraise_value_error():raiseadd_code(ValueError("Invalid value"),400)/exception-HTTP 400 Bad Request{"detail":"Bad Request","message":"Invalid value"}How to contributePrerequisitesPython ^3.9poetry ^1.1.14pre-commit ^2.20.0Install requirementsInstall PoetryPoetry is a tool for dependency management and packaging in Python. It allows
you to declare the libraries your project depends on and it will manage
(install/update) them for you.To install poetry you can follow the official documentation on the page according
to your operating system.Poetry InstallationInstall Pre-CommitIt is a multi-language package manager for pre-commit hooks. You specify a list
of hooks you want and pre-commit manages the installation and execution of any
hook written in any language before every commit.To install poetry you can follow the official documentation on the page according
to your operating system.Pre-Commit InstallationInstall hookspre-commitinstallDependenciesInstall dependenciespoetryinstallYou can also follow the documentation of poetry for a better use of this or any
questions.Poetry Basic UsageAdd dependencyThey are the dependencies that the package needs to work.poetryadd<package>poetryaddfastapiAdd dev dependencyThese are the dependencies that you need only for development,
for example those that are needed to test the package.poetryadd-D<package>poetryadd-DrequestsTestsRun testStatic testThe analysis or static test is run using pre-commit, you can run a specific
analysis using the id, or run all testsSingle testpre-commitrunpylint⚠️ Pre-commit by default only runs on files modified in stage.
If you want to run on all files you can add the--all-filesflag.All testpre-commitrunAll filespre-commitrun--all-files
pre-commitrunblack--all-filesUnittestpoetryrunpytest-v