Deeper tracebacks?

brooklineTom BrooklineTom at gmail.com
Wed Dec 10 23:48:01 EST 2008


On Dec 10, 10:49 pm, "Chris Rebert" <c... at rebertia.com> wrote:
> On Wed, Dec 10, 2008 at 3:50 PM, brooklineTom <Brookline... 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

I understand that there is no method named "zork". The attempted call
to zork occurred in the method named "error", *not* the method named
"perform_". I suggest that the failing method is "error", and the
reported line number should be the line that contains "int(3).zork".

Specifically, I think that aRawStack should contain the following:

>>> aRawStack[8][3]
"answer = anObject.perform_('error')"

>>> aRawStack[9][3]
"answer = anObject.error()"

>>> aRawStack[10][3]
'aRawStack = traceback.extract_stack()'

The entry at aRawStack[9] is the stack frame that I suggest is
missing.

Thx,
Tom



More information about the Python-list mailing list