Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make Fastapi put the stacktrace in the body when handling 500 error #1241

Closed
3 tasks done
allan-simon opened this issue Apr 11, 2020 · 11 comments
Closed
3 tasks done
Labels
question Question or problem question-migrate

Comments

@allan-simon
Copy link

First check

  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.

Description

During the development cycle, especially when running on a remote machine (QA environment etc.) it's pretty convenient to have the traceback directly in the body of a 500 response so that one does not have to connect to the machine to get the traceback.

Of course it's something that one should opt-in , as you don't want to have that in production

@allan-simon allan-simon added the question Question or problem label Apr 11, 2020
@phy25
Copy link

phy25 commented Apr 11, 2020

You could start with https://fastapi.tiangolo.com/tutorial/handling-errors/#install-custom-exception-handlers with a call to a function in traceback module.

@allan-simon
Copy link
Author

ah yeah right , stupid me, thanks for the pointer, I will try to come up with something and put it here in case somebody wonders the same thing

@allan-simon
Copy link
Author

allan-simon commented Apr 12, 2020

ok I've hacked this and it seems to work pretty well

if DISPLAY_TRACEBACK_ON_500:

    @app.exception_handler(Exception)
    async def debug_exception_handler(request: Request, exc: Exception):
        import traceback

        return Response(
            content="".join(
                traceback.format_exception(
                    etype=type(exc), value=exc, tb=exc.__traceback__
                )
            )
        )

@phy25
Copy link

phy25 commented Apr 12, 2020

You may want to close the issue if it works for you :)

@allan-simon
Copy link
Author

haha sure

@tiangolo
Copy link
Member

Thanks for the help here @phy25 ! 🍰 🙇

Thanks @allan-simon for coming back to close it 👍

@retnikt
Copy link
Contributor

retnikt commented Apr 28, 2020

Starlette has a built-in server exception middleware - use FastAPI(debug=True) to enable it

@mhulo
Copy link

mhulo commented Oct 7, 2020

Starlette has a built-in server exception middleware - use FastAPI(debug=True) to enable it

The fact that you can set debug=true is mentioned in several places, but not where to or how to. I finally saw your reply after 2hrs of googling. Would be great to get this into the fastapi docs.

@yifeikong
Copy link

I can get FastAPI to print stack trace with debug=True, but how to make FastAPI print the trackback on command line?

@mhulo
Copy link

mhulo commented Aug 17, 2021

Surprisingly (to me) its late 2021 and the starlette debug traceback response whilst pretty, still does not show the local vars - as other frameworks do (eg. django).. and this was essential to me migrating some existing projects to fastApi.

My crude workaround is as follows;

if (custom_debug == True):
  @app.exception_handler(Exception)
  async def debug_exception_handler(request: Request, exc: Exception):

      import stackprinter
      sp = stackprinter.format(reverse=True)

      sp = sp.replace('<', '&lt; ')
      sp = sp.replace('>', '&gt; ')
      sp = sp.replace('--\n\nFile', '--|||File')
      sp = sp.replace('..\n\nFile', '..|||File')
      sp_arr = sp.split('|||')
     
      main = ''
      for i in sp_arr:
        main += '<div class="sect"><pre>' + i + '</pre></div><br>\n'

      resp =  '''
        <html>
          <head>
            <style type="text/css">
              body { border: 1px #038BB8 solid; }
              .hdr { border-bottom: 20px #038BB8 solid; padding-top: 1px; padding-left: 10px; }
              .sect { padding: 10px; background: #E4F4FD; border: 1px #c7dce8 solid; border-width: 1px 0px; }
            </style>
          </head>
          <body>
            <div class="hdr">
              <h2>500 Server Error:</h2>
            </div>
            <br>
          '''
      resp += main
      resp += '<body></html>'
        
      return HTMLResponse(content=resp)

@tibbe
Copy link

tibbe commented Jun 4, 2022

What are the pros/cons of this approach:

import logging
from typing import Callable

from fastapi import FastAPI, Response
from fastapi.exceptions import HTTPException, RequestValidationError
from fastapi.routing import APIRoute
from starlette.requests import Request

class ServerErrorLoggingRoute(APIRoute):
    '''Log uncaught exceptions.'''

    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            try:
                return await original_route_handler(request)
            # These exceptions are used for control flow rather to indicate a
            # server error so we don't log these.
            except RequestValidationError:
                raise
            except HTTPException:
                raise
            except Exception:
                logging.exception('Uncaught exception')
                raise

        return custom_route_handler

app = FastAPI()
app.router.route_class = ServerErrorLoggingRoute

@tiangolo tiangolo changed the title [QUESTION] How to make Fastapi put the stacktrace in the body when handling 500 error How to make Fastapi put the stacktrace in the body when handling 500 error Feb 24, 2023
@tiangolo tiangolo reopened this Feb 28, 2023
@fastapi fastapi locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #7519 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

7 participants