Issue1230540
Created on 2005-06-30 19:06 by ellisj, last changed 2011-09-11 18:55 by Nikratio.
| Messages (6) | |||
|---|---|---|---|
| msg25694 - (view) | Author: Jonathan Ellis (ellisj) | Date: 2005-06-30 19:06 | |
simple script to reproduce:
import sys, threading
def log_exception(*args):
print 'got exception %s' % (args,)
sys.excepthook = log_exception
def foo():
a = 1 / 0
threading.Thread(target=foo).start()
Note that a normal traceback is printed instead of "got
exception."
|
|||
| msg25695 - (view) | Author: Michael Hudson (mwh) ![]() |
Date: 2007-06-06 11:11 | |
I've just run into this, and it's very annoying. The stupid part is that threads started with the thread module don't have this problem, it's just a problem with threading.Thread()s trying to be too clever. I would vote for deleting all the code to do with exception printing in threading.py and letting the C machinery take care of it. |
|||
| msg25696 - (view) | Author: Jonathan Ellis (ellisj) | Date: 2007-06-15 02:04 | |
Here is a workaround in the meantime:
def install_thread_excepthook():
"""
Workaround for sys.excepthook thread bug
(https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
Call once from __main__ before creating any threads.
If using psyco, call psycho.cannotcompile(threading.Thread.run)
since this replaces a new-style class method.
"""
import sys
run_old = threading.Thread.run
def run(*args, **kwargs):
try:
run_old(*args, **kwargs)
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.excepthook(*sys.exc_info())
threading.Thread.run = run
|
|||
| msg62933 - (view) | Author: Tiago Alves (tiagoaoa) | Date: 2008-02-24 20:40 | |
I don't see it as a problem or as the threading module trying to be "clever". It clearly was a design choice to make the module have its own exception treatment in order to make it clear in which thread the exception occurred. IMHO the decision here should be to implement per thread excepthook's. |
|||
| msg91243 - (view) | Author: Ian Beaver (undercoveridiot) | Date: 2009-08-03 21:59 | |
I found that the workaround suggested doesn't work when you have a
subclass of threading.Thread and you want to catch everything in the
module that contains the class to a common log.
Say you have a module with a socket server that spawns a thread on
accept and you want to log anything that tracebacks in the module. This
seems to work:
import sys
import logging
from functools import wraps
def myExceptHook(type, value, tb):
""" Redirect tracebacks to error log """
import traceback
rawreport = traceback.format_exception(type, value, tb)
report = '\n'.join(rawreport)
log.error(report)
sys.excepthook = myExceptHook
def use_my_excepthook(view):
""" Redirect any unexpected tracebacks """
@wraps(view)
def run(*args, **kwargs):
try:
return view(*args, **kwargs)
except:
sys.excepthook(*sys.exc_info())
return run
Then in your thread subclass:
class MyThread(threading.Thread):
def __init__(self, socket_conn):
threading.Thread.__init__(self)
self.my_conn = socket_conn
@use_my_excepthook
def run(self):
""" Do stuff """
|
|||
| msg91244 - (view) | Author: Ian Beaver (undercoveridiot) | Date: 2009-08-03 22:24 | |
Instead of using decorators, this is a slightly simpler modification to
the proposed workaround that allows for any subclassed run method to
also be caught.
def installThreadExcepthook():
"""
Workaround for sys.excepthook thread bug
From
http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html
(https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
Call once from __main__ before creating any threads.
If using psyco, call psyco.cannotcompile(threading.Thread.run)
since this replaces a new-style class method.
"""
init_old = threading.Thread.__init__
def init(self, *args, **kwargs):
init_old(self, *args, **kwargs)
run_old = self.run
def run_with_except_hook(*args, **kw):
try:
run_old(*args, **kw)
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.excepthook(*sys.exc_info())
self.run = run_with_except_hook
threading.Thread.__init__ = init
|
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2011-09-11 18:55:28 | Nikratio | set | nosy:
+ Nikratio |
| 2010-08-04 04:44:18 | terry.reedy | set | stage: test needed versions: + Python 2.7, Python 3.2, - Python 2.6, Python 2.5 |
| 2010-02-23 21:22:52 | eric.araujo | set | nosy:
+ eric.araujo |
| 2009-08-03 22:24:03 | undercoveridiot | set | messages: + msg91244 |
| 2009-08-03 21:59:32 | undercoveridiot | set | nosy:
+ undercoveridiot messages: + msg91243 |
| 2008-02-24 20:40:08 | tiagoaoa | set | nosy:
+ tiagoaoa messages: + msg62933 |
| 2007-11-23 09:20:55 | christian.heimes | set | versions: + Python 2.6, Python 2.5, - Python 2.4 |
| 2005-06-30 19:06:10 | ellisj | create | |
