Deeper tracebacks?

Chris Rebert clp at rebertia.com
Wed Dec 10 22:49:03 EST 2008


On Wed, Dec 10, 2008 at 3:50 PM, brooklineTom <BrooklineTom at gmail.com> wrote:
> On Dec 10, 5:03 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>> En Wed, 10 Dec 2008 16:59:16 -0200, brooklineTom <Brookline... at gmail.com>
>> escribió:
>>
>> > I want my exception handler to report the method that originally
>> > raised an exception, at the deepest level in the call-tree. Let give
>> > an example.
>>
>> That's the default behavior, you don't have to do anything special.
>>
>> > import sys, traceback
>> > class SomeClass:
>> >     def error(self):
>> >         """Raises an AttributeError exception."""
>> >         int(3).zork()
>>
>> >     def perform_(self, aSelector):
>> >         try:
>> >             aMethod = getattr(self, aSelector, None)
>> >             answer = apply(aMethod, [], {})
>> >         except: AttributeError, anAttributeErrorException:
>> >             aRawStack = traceback.extract_stack()
>> >             answer = None
>>
>> (I assume you're using Python < 3.0)
>> Use the 3-names form of the except statement:
>>
>>          try:
>>              aMethod = getattr(self, aSelector, None)
>>              answer = aMethod()
>>          except AttributeError, e, tb:
>>              # the tb variable holds the traceback up to the error
>>              # the same thing you see printed by Python when
>>              # an unhandled error happens
>>              answer = None
>>
>> Alternatively, you can obtain the same thing with sys.exc_info()[2]
>> Remember to delete any reference to the traceback object as soon as you're
>> done with it; seehttp://docs.python.org/library/sys.html#sys.exc_info
>>
>> --
>> Gabriel Genellina
>
> I'm using Python 2.5.
>
> As I understand it, "aRawStack" (above) has the same information as
> sys.exc_info()[2].
>
> The deepest entry in aRawStack is the perform_ invocation. The
> contents of the two bottom-most stack frames are:
>>>> aRawStack[8][3]
> "answer = anObject.perform_('error')"
>>>> aRawStack[9][3]
> 'aRawStack = traceback.extract_stack()'
>
>
> By the time the handler is called, "zork" -- the method that was
> called when the exception was raised, and "error", the method that
> invoked zork, have already been removed from the stack.

There is no zork() method, so it *can't have been called* and
therefore *can't be in the traceback*. The error lies in the method
that's trying to call a _nonexistent_ method, and that's where Python
reports the error.

Recall that:
x.zork()

is equivalent to:
_z = x.zork #error occurs here, in the attribute lookup
_z() #Python never gets here

So no call takes place because you get an AttributeError before Python
can get any further. zork() would only in the traceback if (1) it was
looked up and called successfully [not the case here] and (2) an error
occurred in zork()'s method body [again, not the case because it's not
defined].

Cheers,
Chris

-- 
Follow the path of the Iguana...
http://rebertia.com


More information about the Python-list mailing list