[IPython-dev] excepthook-like behavior in ipython

Erik Tollerud erik.tollerud at gmail.com
Mon May 14 05:25:28 EDT 2012


This at first seemed to work, but I've discovered a test case where it
fails.  If I paste exactly what you have here into IPython, and then
do ``raise ValueError('a message')``, it works exactly as expected.
However, if instead I do ``raise Exception('a message')``, I get a
traceback like what I've shown below.  Further investigation has
revealed that it only happens if I try to raise an exception of a
class exactly the same as what's given in the first argument to
set_custom_exc (Exception, in this case), while if I raise
sub-exceptions, everything works just fine.  Is this a bug, or am I
mis-using it somehow?

(if I execute the Min's example, and then do ``raise Exception``):

... the "hi <type 'exceptions.Exception'>" message repeats for the
length of the recursion limit...
hi <type 'exceptions.Exception'>
Custom TB Handler failed, unregistering
Custom TB Handler failed, unregistering
Custom TB Handler failed, unregistering
Custom TB Handler failed, unregistering
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.
hi Traceback (most recent call last):
  File "/home/erik/src/ipython/IPython/core/ultratb.py", line 756, in
structured_traceback
Custom TB Handler failed, unregistering
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.
Traceback (most recent call last):
  File "/home/erik/src/ipython/IPython/core/ultratb.py", line 756, in
structured_traceback
    records = _fixed_getinnerframes(etb, context, tb_offset)
  File "/home/erik/src/ipython/IPython/core/ultratb.py", line 242, in
_fixed_getinnerframes
    records  = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
  File "/usr/lib/python2.7/inspect.py", line 1043, in getinnerframes
    framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
  File "/usr/lib/python2.7/inspect.py", line 1003, in getframeinfo
    filename = getsourcefile(frame) or getfile(frame)
  File "/usr/lib/python2.7/inspect.py", line 444, in getsourcefile
    filename = getfile(object)
  File "/usr/lib/python2.7/inspect.py", line 404, in getfile
    if isclass(object):
  File "/usr/lib/python2.7/inspect.py", line 65, in isclass
    return isinstance(object, (type, types.ClassType))
RuntimeError: maximum recursion depth exceeded while calling a Python object

Unfortunately, your original traceback can not be constructed.

The original exception:
---------------------------------------------------------------------------
(<type 'exceptions.Exception'>, Exception(), <traceback object at
0x1850998>)Traceback (most recent call last)
(<type 'exceptions.Exception'>, Exception(), <traceback object at
0x1850998>): None






On Mon, Apr 9, 2012 at 7:09 PM, MinRK <benjaminrk at gmail.com> wrote:
>
>
> On Mon, Apr 9, 2012 at 18:39, Erik Tollerud <erik.tollerud at gmail.com> wrote:
>>
>> Hello all,
>>
>> I noticed some odd (although I now realize quite sensible) behavior in
>> IPython, and I'm curious if there's a workaround.  I have an
>> application log that I want to use to capture unhandled exceptions.
>> When not using IPython, it's straightforward to just override
>> sys.excepthook to first sent the exception to our logging system, and
>> then continue the normal excepthook behavior.  However, IPython seems
>> to always use only its own excepthook in interactive mode
>> (TerminalInteractiveShell.excepthook, at least in the standard
>> terminal).
>>
>> So my question is: Is there any way to plug anything into the IPython
>> exception handling system, either with sys.excepthook-style syntax, or
>> some other way?  As I said, it doesn't have to actually catch the
>> exceptions - we just want entries placed in a log if an interactive
>> session hits an unhandled exception, and it could then pass normally
>> into the IPython formatting/pdb running system.
>
>
> You use shell.set_custom_exc for this:
>
> # define custom exception handler:
>
> def custom_exc(shell, etype, evalue, tb, tb_offset=None):
>     # do you own thing:
>     print 'hi', etype
>     # also do what IPython would have done, if you want:
>     shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)
>
> # Tell IPython to use it for any/all Exceptions:
> get_ipython().set_custom_exc((Exception,), custom_exc)
>
>>
>> --
>> Erik Tollerud
>> _______________________________________________
>> IPython-dev mailing list
>> IPython-dev at scipy.org
>> http://mail.scipy.org/mailman/listinfo/ipython-dev
>
>
>
> _______________________________________________
> IPython-dev mailing list
> IPython-dev at scipy.org
> http://mail.scipy.org/mailman/listinfo/ipython-dev
>



-- 
Erik Tollerud



More information about the IPython-dev mailing list