How do I make Django signal handlers not fail sile

2019-03-23 09:17发布

问题:

How do I make Django signal handlers not fail silently when an exception is encountered in the handler?

Is there a place where all these errors are logged while using development server?

Why do django signal handlers fail silently anyway? Isn't it against one of the lines in Zen of Python?

Zen of Python clearly states...

Errors should never pass silently.

It makes them a nightmare to debug. All you can see is that the signal is not getting fired...

I found this question but the answer is useless to me as it is very specific to the question (answer suggests using pyflakes, I already use pydev which does satisfactory static analysis)

回答1:

When using manage.py shell I get an uncaught exception when manually creating a FollowTable from your example. However, uncaught exceptions during a request don't show up in the terminal (other than showing that 500 was returned), instead they are shown in the browser. If you're using JavaScript to make requests you might want to look in firebug/chrome developer tools to see if it's returning a traceback.

Looks like someone else has answered how to get tracebacks to show in the console: https://stackoverflow.com/a/5886462/725359

Seemed to work for me. I did the following:

  1. Added the ExceptionLoggingMiddleware class to my_app/__init__.py
  2. Added 'my_app.ExceptionLoggingMiddleware' to MIDDLEWARE_CLASSES in settings.py
  3. Restarted the development server


回答2:

Yes, errors should never fail silently

Yes, I think like you: errors should never fail silently

Built in signals don't fail silently

Django's built in signals don't fail silently because they use send()

Only send_robust() ignores exceptions

Docs from send_robust()

send_robust() catches all errors derived from Python’s Exception class, and ensures all receivers are notified of the signal. If an error occurs, the error instance is returned in the tuple pair for the receiver that raised the error.

Conclusion

Since django doesn't use send_robust() please investigate where it gets called. I guess it is in your source code, or in the code of a third party app.