why logging re-raise my exception and can't be caught?

D

daniel

I use a simple program to illustrate the problem:

import logging

def foo() :
raise ValueError("foo")

if __name__ == "__main__" :
try :
foo()
except ValueError :
logging.exception("caught here") -- seems re-raise the
exception and can't be caught
print "caught here" --- just works.

I'm expecting the exception to be caught silently, and print the msg to
some place, if I comment out the logging statement, it just works, but
now, the stack trace is printed as if the except statement was not
there!!

how could this happen, just weird.. can I make the logging module
behave as I expected?

tks in advance.

daniel
 
B

Ben Finney

daniel said:
I'm expecting the exception to be caught silently, and print the msg to
some place

Then why not use logging.error() ?

<URL:http://docs.python.org/lib/module-logging>
=====
error(msg[, *args[, **kwargs]])
Logs a message with level ERROR on the root logger. The arguments
are interpreted as for debug().

exception(msg[, *args])
Logs a message with level ERROR on the root logger. The arguments
are interpreted as for debug(). Exception info is added to the
logging message. This function should only be called from an
exception handler.
=====

A 'try ... except' statement is not an exception handler. So, if you
want to log the fact that an error occurred, it seems logging.error()
is the correct choice.
 
D

Diez B. Roggisch

daniel said:
I use a simple program to illustrate the problem:

import logging

def foo() :
raise ValueError("foo")

if __name__ == "__main__" :
try :
foo()
except ValueError :
logging.exception("caught here") -- seems re-raise the
exception and can't be caught
print "caught here" --- just works.

I'm expecting the exception to be caught silently, and print the msg to
some place, if I comment out the logging statement, it just works, but
now, the stack trace is printed as if the except statement was not
there!!

how could this happen, just weird.. can I make the logging module
behave as I expected?

For starters - reading the documentation. The logging.exception-call
precisely is for printing the exception as if it was not caught at all.

If you don't want that, don't use it - use one of the error, warn, info
or debug calls.

Diez
 
D

daniel

thank your so much firstly.

I feel really ashamed...

I think I did read through all examples and docs, but I just took for
granted that all the info(), warning(), debug() like functions behaves
much alike except the level name.. so the description you listed really
was ignored,,

tks again for your help.. I do appreciate it.

daniel
 
S

Steve Holden

Ben Finney wrote:
[...]
A 'try ... except' statement is not an exception handler. [...]

Just as a matter of interest, what would your definition of an exception
handler be, then? Specifically, what's the "except" clause for?

The docs for looging.except should make it explicit that the exception
will be re-raised.

Of course it might be possible to do something hackish like

try:
...
except:
try:
logging.exception(...)
except:
pass

which (although untested) should theoretically allow the catching (for a
second time) of teh exception reraised by logging.exception().

regards
Steve
 
G

Georg Brandl

Steve said:
Ben Finney wrote:
[...]
A 'try ... except' statement is not an exception handler. [...]

Just as a matter of interest, what would your definition of an exception
handler be, then? Specifically, what's the "except" clause for?

The docs for looging.except should make it explicit that the exception
will be re-raised.

Of course it might be possible to do something hackish like

try:
...
except:
try:
logging.exception(...)
except:
pass

which (although untested) should theoretically allow the catching (for a
second time) of teh exception reraised by logging.exception().

Use the source, people. The exception is not reraised. The only effect of
exception() versus error() is that exception() passes the "exc_info=1" keyword
argument to error() which means that the stack trace is added to the
logging message.

The default logger prints to stdout, which is why the stack trace is printed
there too.

(In the sense of the logging docs, an except:-clause *IS* an error handler).

Georg
 
B

Ben Finney

Steve Holden said:
Ben Finney wrote:
[...]
A 'try ... except' statement is not an exception handler. [...]

Just as a matter of interest, what would your definition of an
exception handler be, then? Specifically, what's the "except" clause
for?

It seems my understanding was wrong. The 'except' clause *is* an
exception handler. (I was thinking that the "default exception
handler" was the only thing that could be called an "exception
handler".) It's explained better here:

said:
The docs for looging.except should make it explicit that the
exception will be re-raised.

Yes, I agree; it wasn't very clear on reading the description of
'logging.exception()' what would actually happen.
Of course it might be possible to do something hackish like

try:
...
except:
try:
logging.exception(...)
except:
pass

which (although untested) should theoretically allow the catching
(for a second time) of teh exception reraised by
logging.exception().

It does seem rather a side effect, and an unexpected (and
undocumented) one at that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top