question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Clarifying HTTP exception behavior wrt. 500 responses.

See original GitHub issue

Related: #54

Having worked through the implementation implications in both uvicorn and starlette, I’m now confident that the behaviors should be:

  • Servers should log the exception. The must check if a response has been started, and must send a 500 if no response has been sent. They should not issue any particular warning if an exception is raised once a response has already been sent, as this represents normal behavior for a well-behaved application, although they may issue an explicit warning in the case of an exception where the response has started but not completed.
  • Applications may choose to catch exceptions, and send an appropriate 500 page (eg. debug traceback or user-facing 500 error page) if the response has not yet started. If they do so then they must subsequently still raise the exception. This behavior enables the server to continue to log the traceback as desired, and makes the exception visible to any error-monitoring middleware.

Both Uvicorn’s WSGI middleware and asgiref’s WsgiToAsgi appear to have incorrect behavior here, in that they raise exc_info immediately in both cases, rather than sending an application’s 500 response that is returned alongside with the exc_info and then raising the exception. (End result - the server gets to log the exception and returns a 500 response, but we don’t get any application-defined 500 responses, either traceback or user-facing 500s)

An example of what I’ve used to test server/application interaction for resolving this wrt uvicorn’s middleware… Taken from the WSGI spec

import uvicorn
import sys


def app(environ, start_response):
    try:
        # regular application code here
        raise RuntimeError()
        status = "200 Froody"
        response_headers = [("content-type", "text/plain")]
        start_response(status, response_headers)
        return [b"normal body goes here"]
    except:
        # XXX should trap runtime issues like MemoryError, KeyboardInterrupt
        #     in a separate handler before this bare 'except:'...
        status = "500 Oops"
        response_headers = [("content-type", "text/plain")]
        start_response(status, response_headers, sys.exc_info())
        return [b"error body goes here"]


if __name__ == '__main__':
    uvicorn.run(app, wsgi=True)

Here’s my resolution to the issue in uvicorn - note that exc_info needs to be raised not at the end of start_response (since we don’t have the response body yet) but after all of the returned byte-iterator has been sent to the send channel.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
andrewgodwincommented, Sep 14, 2018

OK - I won’t be able to get to either in the short term, but will leave this open to track the work.

0reactions
andrewgodwincommented, Jun 24, 2019

@tomchristie Do you think there’s more work we need to do here?

Read more comments on GitHub >

github_iconTop Results From Across the Web

HTTP status code 500 for NotFoundException - Stack Overflow
I encounter some problem. I found the root cause. The built-in exception handle is only occur in resteasy newest version build 2.3.1 GA....
Read more >
Exception Handling in ASP.NET Web API - Microsoft Learn
The HttpResponseException type is a special case. This exception returns any HTTP status code that you specify in the exception constructor.
Read more >
Scalable Vector Graphics (SVG) 1.1 Specification Errata
The behavior of "to animations" and "by animations" when using animateTransform is unclear. Resolution, Clarify that a "by animation" is equivalent to an ......
Read more >
Changelog — Python 3.11.1 documentation
gh-100001: python -m http.server no longer allows terminal control ... gh-61162: Clarify sqlite3 behavior when How to use the connection ...
Read more >
Assessing the Theory and Practice of Criminal Sentencing
'explaining the present and past behavior of others and by predicting with ... general agreement that judges exhi bit patterned responses, what accounts...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found