gunicorn
gunicorn copied to clipboard
Consistent exception handling for 4XX and 5XX errors
I find it odd how different ParseException (or any error outside the application, really) is handled in different ways depending on configuration and specific error. I think this can be simplified by pushing the status, reason and message up and treating all exceptions in one code block.
They are all alike, really. They could subclass something that gives the basic structure of error messages associated with certain HTTP status codes and ASCII reason summaries e.g.
- https://github.com/pajod/gunicorn/blob/e9f0fa8/gunicorn/workers/base.py#L220
- https://github.com/pajod/gunicorn/blob/e9f0fa8/gunicorn/http/errors.py#L12
And the fact that --reload
has an implicit side-effect that cannot be independently configured is also a bit surprising and inflexible. One idea I have is to introduce a new option, which merely defaults to automatically selecting the error-handler, but can be overridden if so desired.
I was thinking of a --on-fatal=[world-readable|refuse|quiet|guess]
option, where only guess
exposes potentially-meant-private code depending on whether it believes this is a non-public non-production environment e.g.
- https://github.com/pajod/gunicorn/blob/e9f0fa8/gunicorn/config.py#L2403
- https://github.com/pajod/gunicorn/blob/e9f0fa8/gunicorn/workers/base.py#L142
But maybe instead of 3-4 fixed choices, it should be a hook that can do anything (make_fail_app or otherwise). I am not certain about how that hook would work and be documented, to cover those 3-4 cases (and possibly more), and still not produce unexpected resources if that hook in turn triggers another exception.
Ideas?
I've also considered that maybe we should have a --dev
option. This would cause --reload
to default on, --reuse-port
to default off (and we make it on by default otherwise), and maybe there are other options. Sending tracebacks to the browser in development mode is convenient.