Change default behavior of uncaught exception handling in python
Asked Answered
T

2

5

I went through "Logging uncaught exceptions in Python". And, I have tried this:

import web
import sys

app = web.application((
  '/test', 'test'), globals())

def test_func(e_type, value, traceback):
  print "Handled exception here.."

class test:
  def GET(self):
    a = 1/0

if __name__ == "__main__":
  sys.excepthook = test_func
  app.run()

Here, you can easily see if GET /test request comes in, I am deliberately raising ZerDivisionError. As i have overriden sys.excepthook, I expect method test_func to execute on ZeroDivisionError.

Whereas, this piece of code is not working as per expectation. I have observed that when i try to override excepthook in standalone code (not in web-app), it works fine. New method(overriden) is called properly.

Any idea why is this different behavior ?

Taka answered 15/9, 2013 at 9:48 Comment(2)
Which web app are you using? The most likely reason is that the web-app has decided that this is too dangerous a feature to allow you to play with.Gamosepalous
I did not get 'which web-app?' I am using web.py here. And i have for example written a small web service here, exposing /test.Taka
C
3

Python doc says

sys.excepthook(type, value, traceback)

This function prints out a given traceback and exception to sys.stderr.

So this sys.excepthook is called when a exception needs to printed to terminal. Now you see, web.py itself handles the exceptions. If you dont assign the sys.excepthook, webpy captures the exception and shows the exception in browser. And as web.py is itself handling the exceptions, setting sys.excepthook makes no change. If web.py didn't handle the exception itself, then it would be uncaught and sys.excepthook would be called.

If you really want to handle exception yourself in this code, try searching web.py doc and source code to figure out how web.py handles exceptions and customize that.

python doc also says

sys.__excepthook__

These objects contain the original values of displayhook and excepthook at the start of the program. They are saved so that displayhook and excepthook can be restored in case they happen to get replaced with broken objects.

So my guess is web.py using that, so your custom handler is not called.

Counteraccusation answered 15/9, 2013 at 10:23 Comment(0)
A
6

Using web.py, one way of catching exceptions yourself would be to add a custom processor:

...
def error_processor(handler):
   try:
       handler()
   except:
       # do something reasonable to handle the exception
       return 'something happened...'

app.add_processor(error_processor)
app.run()
...

Otherwise web.py will catch the exception and show a default error message instead.

Acarpous answered 15/9, 2013 at 10:50 Comment(5)
Thanks @Acarpous I tried this one. The problem with this is, if something goes wrong in the code then the exception catched is '500 Internal Server Error'. I want actual exception / error thrown from the code. Any way to achieve this ?Taka
Seems like only instances of HTTPError are re-reaised when calling the processors, everything else is converted to a blank internalError, so this unfortunately will only work for HTTPErrors.Acarpous
anyother solution you can think of? Or shall I go ahead and do the changes in web.py itself ? I don't prefer the second one.Taka
I can't really think of an ohter solution. I agree, changing the source of an external library isn't a really good way, in such cases I prefer to monkeypatch it. here I've prepared a small example on how this could work for that case, hope it helps.Acarpous
Thanks @Acarpous for apt reply. Yes, monkeypatching is a good idea and makes sense. Thanks for the example.Taka
C
3

Python doc says

sys.excepthook(type, value, traceback)

This function prints out a given traceback and exception to sys.stderr.

So this sys.excepthook is called when a exception needs to printed to terminal. Now you see, web.py itself handles the exceptions. If you dont assign the sys.excepthook, webpy captures the exception and shows the exception in browser. And as web.py is itself handling the exceptions, setting sys.excepthook makes no change. If web.py didn't handle the exception itself, then it would be uncaught and sys.excepthook would be called.

If you really want to handle exception yourself in this code, try searching web.py doc and source code to figure out how web.py handles exceptions and customize that.

python doc also says

sys.__excepthook__

These objects contain the original values of displayhook and excepthook at the start of the program. They are saved so that displayhook and excepthook can be restored in case they happen to get replaced with broken objects.

So my guess is web.py using that, so your custom handler is not called.

Counteraccusation answered 15/9, 2013 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.