[ACCEPTED]-How to catch an exception in python and get a reference to the exception, WITHOUT knowing the type?-jython
You can reference exceptions using the sys
module. sys.exc_info
is 2 a tuple of the type, the instance and the 1 traceback.
import sys
try:
# some call to a java lib that raises an exception here
except:
instance = sys.exc_info()[1]
FWIW, I have found that if you add this 3 import to your Jython script:
from java.lang import Exception
and just use 2 the conventional Python Exception handler:
except Exception, e:
it 1 will catch both Python exceptions and Java exceptions
Just for anyone interested... I spent a 12 bit of time testing stuff because I wanted 11 to find out how to get a proper stack trace 10 whether a Python Exception (BaseException 9 in fact, which is the base class) or a java.lang.Throwable 8 (java base class for Exception, Error, etc.) is 7 thrown... this code illustrates how to catch 6 all line number refs correctly.
import sys
import traceback
import java
print "hello world"
def custom_hook( type, exc, tb ):
if isinstance( sys.exc_info()[ 1 ], java.lang.Throwable ):
sys.stderr.write( "AS JAVA:\n" )
sys.exc_info()[ 1 ].printStackTrace() # java part
else:
sys.stderr.write( "NO JAVA TRACE:\n" )
sys.stderr.write( "AS PYTHON:\n" )
traceback.print_exc()
# useful for custom exception handling!
sys.excepthook = custom_hook
def handle_exc():
# generate either a java.lang.Throwable (uncomment the next line and comment out "a = 16 / 0"
# java.lang.String( None )
# OR... a python-style BaseException:
a = 16 / 0
class Task( java.lang.Runnable ):
def run( self ):
# NB the problem with all this stuff is that the Java stack trace shows
# a java.lang.Throwable occurring at the last line of this code block...
# print "lots of stuff first"
# print "lots 2"
# handle_exc()
# print "lots 3"
# print "lots of stuff after"
try:
print "lots of stuff first"
print "lots 2"
handle_exc()
print "lots 3"
print "lots of stuff after"
# NB do not catch both (Python) BaseException and java.lang.Throwable...
# except ( BaseException, java.lang.Throwable ), e:
# the above means that the line no. in handle_exc is not shown when a BaseException
# is thrown...
except java.lang.Throwable, t:
tb = sys.exc_info()[ 2 ]
sys.stderr.write( "java.lang.Throwable thrown at: %s\n" % tb.tb_lineno )
raise t
java.awt.EventQueue.invokeAndWait( Task() )
After this 5 one might think of writing a decorator to 4 precede def run( self ) and similar methods 3 so that you don't have to write out this 2 catch-the-Throwable try-except block each 1 time... specifically:
def throw_trap( function ):
def wrapper(*args, **kvargs):
try:
return function( *args, **kvargs )
except java.lang.Throwable, t:
tb = sys.exc_info()[ 2 ]
while( tb ):
sys.stderr.write( "thrown at: %s\n" % tb.tb_lineno )
tb = tb.tb_next
raise t
return wrapper
def handle_exc():
java.lang.String( None )
# a = 16 / 0
class Task( java.lang.Runnable ):
@throw_trap
def run( self ):
print "lots of stuff first"
print "lots 2"
handle_exc()
print "lots 3"
print "lots of stuff after"
java.awt.EventQueue.invokeAndWait( Task() )
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.