#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.


Reply via email to