Opened 8 years ago
Last modified 8 years ago
#28244 closed Uncategorized
Exceptions inheriting from BaseException instead of Exception are not correctly handled — at Initial Version
Reported by: | alexpirine | Owned by: | nobody |
---|---|---|---|
Component: | Uncategorized | Version: | 1.11 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hello,
Python documentation states:
In Python, all exceptions must be instances of a class that derives from
BaseException
.
Deriving exceptions from Exception
is a recommendation, but does not seem to be an absolute requirement:
programmers are encouraged to derive new exceptions from the
Exception
class or one of its subclasses, and not fromBaseException
.
So, if BaseException
is used instead of Exception
, Django's convert_exception_to_response doesn't catches it, and crashes instead:
def convert_exception_to_response(get_response): @wraps(get_response) def inner(request): try: response = get_response(request) except Exception as exc: response = response_for_exception(request, exc) return response return inner
If you run it on gunicorn with nginx, which is often the case, you will see upstream prematurely closed connection while reading response header from upstream errors, without any additional info, and without any logs whatsoever, even if you properly configured a logging system.
Only running manage.py runserver
will display the full stack trace:
Traceback (most recent call last): File "…/python3.6/wsgiref/handlers.py", line 137, in run self.result = application(self.environ, self.start_response) File "…/django/contrib/staticfiles/handlers.py", line 63, in __call__ return self.application(environ, start_response) File "…/django/core/handlers/wsgi.py", line 157, in __call__ response = self.get_response(request) File "…/django/core/handlers/base.py", line 124, in get_response response = self._middleware_chain(request) File "…/django/core/handlers/exception.py", line 41, in inner response = get_response(request) File "…/django/utils/deprecation.py", line 140, in __call__ response = self.get_response(request) File "…/django/core/handlers/exception.py", line 41, in inner response = get_response(request) [… and so on, depending on how much middleware you have …] File "…/django/utils/deprecation.py", line 140, in __call__ response = self.get_response(request) File "…/django/core/handlers/exception.py", line 41, in inner response = get_response(request) File "…/django/core/handlers/base.py", line 185, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "…/django/views/decorators/http.py", line 40, in inner return func(request, *args, **kwargs) File "…/your_project/views.py", line 42, in your_func … your_project.YourErrorInheritedFromBaseException: Your error message
Of course I fixed my code by inheriting from Exception
.
But I wonder if catching BaseException
instead of Exception
would be a good change?