From: Pakal on
Hello

I've just realized recently that sys.exc_info() didn't return a full
traceback for exception concerned : it actually only contains the
frame below the point of exception catching.

That's very annoying to me, because I planned to log such tracebacks
with logging.critical(*****, exc_info=True), and these partial
tracebacks, like the one below, are clearly unsufficient to determine
where the problem comes from. A whole traceback, from program entry
point to exception raising point, would be much better.

2010-03-17 09:28:59,184 - pims - CRITICAL - This is just a test to
ensure critical emails are properly sent
Traceback (most recent call last):
<< HERE, lots of frames missing >>
File "test_common.py", line 34, in test_email_sending
os.open("qsdsdqsdsdqsd", "r")
TypeError: an integer is required

Is there any workaround for this ? I've thought about a custom logging
formatter, which would take both the exc_info traceback AND its own
full backtrace, and to connect them together on their relevant part,
but it's awkward and error prone... why can't we just have all the
precious traceback info under the hand there (an additional attribute
might have pointed the precise frame in which the exception was
caught).

Tanks for the attention,
Regards,
Pascal
From: Michael Ricordeau on
Hi,

to log tracebacks, you can probably try traceback module.

I use it like this :

import traceback
..... # your code

for line in traceback.format_exc().splitlines():
log.trace(line)



Le Wed, 17 Mar 2010 03:42:44 -0700 (PDT),
Pakal <chambon.pascal(a)gmail.com> a écrit :

> Hello
>
> I've just realized recently that sys.exc_info() didn't return a full
> traceback for exception concerned : it actually only contains the
> frame below the point of exception catching.
>
> That's very annoying to me, because I planned to log such tracebacks
> with logging.critical(*****, exc_info=True), and these partial
> tracebacks, like the one below, are clearly unsufficient to determine
> where the problem comes from. A whole traceback, from program entry
> point to exception raising point, would be much better.
>
> 2010-03-17 09:28:59,184 - pims - CRITICAL - This is just a test to
> ensure critical emails are properly sent
> Traceback (most recent call last):
> << HERE, lots of frames missing >>
> File "test_common.py", line 34, in test_email_sending
> os.open("qsdsdqsdsdqsd", "r")
> TypeError: an integer is required
>
> Is there any workaround for this ? I've thought about a custom logging
> formatter, which would take both the exc_info traceback AND its own
> full backtrace, and to connect them together on their relevant part,
> but it's awkward and error prone... why can't we just have all the
> precious traceback info under the hand there (an additional attribute
> might have pointed the precise frame in which the exception was
> caught).
>
> Tanks for the attention,
> Regards,
> Pascal
From: Vinay Sajip on
On Mar 17, 10:42 am, Pakal <chambon.pas...(a)gmail.com> wrote:
> Hello
>
> I've just realized recently that sys.exc_info() didn't return a full
> traceback for exception concerned : it actually only contains the
> frame below the point of exception catching.
>
> That's very annoying to me, because I planned to log such tracebacks
> withlogging.critical(*****, exc_info=True), and these partial
> tracebacks, like the one below, are clearly unsufficient to determine
> where the problem comes from. A whole traceback, from program entry
> point to exception raising point, would be much better.
>
> 2010-03-17 09:28:59,184 - pims - CRITICAL - This is just a test to
> ensure critical emails are properly sent
> Traceback (most recent call last):
> << HERE, lots of frames missing >>
>   File "test_common.py", line 34, in test_email_sending
>     os.open("qsdsdqsdsdqsd", "r")
> TypeError: an integer is required
>
> Is there any workaround for this ? I've thought about a customlogging
> formatter, which would take both the exc_info traceback AND its own
> full backtrace, and to connect them together on their relevant part,
> but it's awkward and error prone... why can't we just have all the
> precious traceback info under the hand there (an additional attribute
> might have pointed the precise frame in which the exception was
> caught).
>
> Tanks for the attention,
> Regards,
> Pascal

Do you have a short script which demonstrates the problem? Some more
context is needed. For example, if you have multiple threads of
execution, the traceback will only go up to the top-level function in
the thread.

Regards,

Vinay Sajip
From: Gabriel Genellina on
En Wed, 17 Mar 2010 09:42:06 -0300, Pascal Chambon
<chambon.pascal(a)gmail.com> escribi�:

> traceback functions indeed allow the manipulation of exception
> tracebacks,
> but the root problem is that anyway, since that traceback is incomplete,
> your "traceback.format_exc().splitlines()" will only provide frames for
> callee (downward) functions, not caller (upward) ones, starting from the
> exception catching frame.

Either I don't understand what you mean, or I can't reproduce it:

<code>
import logging

def a(): return b()
def b(): return c()
def c(): return d()
def d(): raise ValueError

def main():
logging.basicConfig(level=logging.DEBUG)
try: a()
except: logging.exception("An error")

main()
</code>

Output:

D:\temp>python test_logging.py
ERROR:root:An error
Traceback (most recent call last):
File "test_logging.py", line 10, in main
try: a()
File "test_logging.py", line 3, in a
def a(): return b()
File "test_logging.py", line 4, in b
def b(): return c()
File "test_logging.py", line 5, in c
def c(): return d()
File "test_logging.py", line 6, in d
def d(): raise ValueError
ValueError

--
Gabriel Genellina

From: Pascal Chambon on
Gabriel Genellina a �crit :
>
> En Wed, 17 Mar 2010 09:42:06 -0300, Pascal Chambon
> <chambon.pascal(a)gmail.com> escribi�:
>
>> traceback functions indeed allow the manipulation of exception
>> tracebacks,
>> but the root problem is that anyway, since that traceback is incomplete,
>> your "traceback.format_exc().splitlines()" will only provide frames for
>> callee (downward) functions, not caller (upward) ones, starting from the
>> exception catching frame.
>
> Either I don't understand what you mean, or I can't reproduce it:
>
>

Allright, here is more concretely the problem :

<code>
import logging

def a(): return b()
def b(): return c()
def c():
try:
return d()
except:
logging.exception("An error")

def d(): raise ValueError

def main():
logging.basicConfig(level=logging.DEBUG)
a()

main()
</code>

OUTPUT:
>>>
ERROR:root:An error
Traceback (most recent call last):
File "C:/Users/Pakal/Desktop/aaa.py", line 7, in c
return d()
File "C:/Users/Pakal/Desktop/aaa.py", line 11, in d
def d(): raise ValueError
ValueError
>>>


As you see, the traceback only starts from function c, which handles the
exception.
It doesn't show main(), a() and b(), which might however be (and are, in
my case) critical to diagnose the severity of the problem (since many
different paths would lead to calling c()).

So the question is : is that possible to enforce, by a way or another,
the retrieval of the FULL traceback at exception raising point, instead
of that incomplete one ?

Thank you for your help,
regards,

Pascal