[ACCEPTED]-How to catch an exception in python and get a reference to the exception, WITHOUT knowing the type?-jython

Accepted answer
Score: 36

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]
Score: 9

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

Score: 5

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