#20752: Error signals are not reliable, especially when dealing with database errors ------------------------------+------------------------------------------ Reporter: tal@… | Owner: nobody Type: Bug | Status: new Component: Core (Other) | Version: 1.5 Severity: Normal | Keywords: signals errors databaseError Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 ------------------------------+------------------------------------------ In core.handlers.base, unhandled exceptions are processed as such:
{{{ except: # Handle everything else, including SuspiciousOperation, etc. # Get the exception info now, in case another exception is thrown later. signals.got_request_exception.send(sender=self.__class__, request=request) response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) }}} Which delivers the error signal to the various handlers (database transaction resets, things like Sentry etc). However, the code that dispatches signals aborts the dispatch if any of the handlers fail (to try..except block): {{{ for receiver in self._live_receivers(_make_id(sender)): response = receiver(signal=self, sender=sender, **named) responses.append((receiver, response)) return responses }}} This is perfectly reasonable in most cases, but is problematic when dealing with top-level error handling, as this prevents the unhandled error from reaching handlers that just want to report it. This is very noticeable in cases where "something bad" happens to the database connection, as the first handler is always the database rollback handler, which only catches DatabaseError, which excludes a lot of errors that can and do crop up in production {{{ def _rollback_on_exception(**kwargs): from django.db import transaction for conn in connections: try: transaction.rollback_unless_managed(using=conn) except DatabaseError: pass }}} I think that it will be better to have the error signal dispatcher defer except raising until after all the handlers were called (or just swallow them all). Alternatively, a different signal for error reporting is possible, but I think that's a little confusing. Thoughts? -- Ticket URL: <https://code.djangoproject.com/ticket/20752> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/058.1ef39f5e0173eca7f679a32bf3f4724a%40djangoproject.com. For more options, visit https://groups.google.com/groups/opt_out.