Thanks.  That did the trick.

 
On 7/31/06, Jim Adrig <jim@trampolining.com> wrote:
On Jul 31, 2006, at 4:15 AM, Codex Sinaiticus wrote:
> I'm using JythonInterpreter inside of java.  When I "eval" a
> script, I'd like to get back whether the script caused an exception
> and information about the execption.  Right now it neither prints
> the info to the output or error streams and I can't find a method
> that will tell me the info.

I am not one of the Jython 'experts'; so there are likely easier ways
to do this; but this is what we use and it works for us;
ExecuteScript is called many times from different places and collects
any script errors into a persistent 'errorList' and is eventually
given back to the user:


%< ------------------------------

public static void ExecuteScript( JythonScript scriptToExec,
PythonInterpreter python, String fillName, int outputPageNumber,
                                    java.util.List errorList, Debug
d ) {
    try {
      if ( scriptToExec != null && scriptToExec.scriptCode != null ) {
        python.exec( scriptToExec.scriptCode );
      }
    } catch ( PyException pe ) {
      // Lots of tricks in here ! :
      HandlePythonException( pe, fillName, Integer.toString
( outputPageNumber ), scriptToExec.scriptSource, errorList, d );
    }
  }

  /**
   *  We try to handle multiple types of exceptions intelligently.
But if we
   *  can't, we just re-throw it so it's caught in the Servlet or
Command-line.
   */
  public static void HandlePythonException( PyException pe, String
fillName, String pageNumber, String pageSource, List errorList,
                                            Debug d ) {
    // trying to get more info ? ('EXECUTION' error in datadump.xml):
    pe.super__printStackTrace ( new java.io.PrintWriter( System.out ) );
//    String locMsg = pe.getLocalizedMessage();

    PyObject exceptionType = pe.type;
    if (exceptionType instanceof PyClass) {   // Python exception
class; maybe a wrapped Java exception:
      String exceptionName = ((PyClass)pe.type).__name__;
      // Handle Java errors wrapped as PyExceptions (Java code
called from Jython code):
      if (exceptionName.startsWith("java.") ||
exceptionName.startsWith ("rms.") ) {
        if (exceptionName.equals("java.lang.NoClassDefFoundError"))
{  // This requires special handling since it does NOT wrap an
exception:

          //PyObject po = pe.value ;
          if ( pe.value instanceof PyJavaInstance ) {
            PyJavaInstance pji = ( PyJavaInstance )pe.value;
            Object obj = pji.__tojava__( NoClassDefFoundError.class );
            NoClassDefFoundError classNotFoundErr =
( NoClassDefFoundError )obj;
            errorList.add( new FillError( "F", "'" + fillName + "',
page " + pageNumber + ": Class not found: " +
classNotFoundErr.getMessage ()) );
            //System.out.println( "message:" + message );
          } else throw pe; // Whenever we don't know what else to
do ...
        } else { // Other exceptions SHOULD wrap 'Exception':
          Exception je = ( Exception )pe.value.__tojava__
( Exception.class );
          String firstStackLine = JavaUtils.getFirstLineFromException
( je );
          String entireStackString =
JavaUtils.getStackStringFromException ( je );
          if ( exceptionName.equals
( "java.lang.IllegalArgumentException" ) ) {
            // Can we do better than this? (need a test case...):
            errorList.add( new FillError( "F",
                    "Illegal Argument Exception in '" + fillName +
"' on page " + pageNumber + ":" + je.getMessage(),
                     firstStackLine ) );
          } else if ( exceptionName.equals
( "rms.fillmagic.FillException" ) ) { // These carry their own type !!
            RmsException re = ( RmsException )je;
            re.setErrorMessage( "'" + fillName + "', page " +
pageNumber + ": " + re.getMessage() ); // Add the page # to it
            //errorList.add( new FillError( fe.getErrorType(),
"FillException on page " + pageNumber + ": " + je.getMessage (),
fe.getFirstLine() ));
            errorList.add( re ); // !FIX! .getFillError() );
          } else if ( exceptionName.equals
( "java.lang.RuntimeException" ) ) { // Make these 'F'atals too ?
            //  Assume these have a good error message passed in the
RuntimeException constructor:
            errorList.add( new FillError( "F", "RuntimeException in
'" + fillName + "' on page " + pageNumber + ": "
                                          + je.getMessage(),
firstStackLine ) );
          } else if ( exceptionName.equals
( "java.lang.NullPointerException" ) ) { // Make these 'F'atals too ?
            //NullPointerException e = (NullPointerException)
pe.value.__tojava__( (new NullPointerException()).getClass() );
            errorList.add( new FillError( "F", "NullPointerException
in '\" + fillName + \"' on page " + pageNumber + ": "
                                          + firstStackLine,
entireStackString ) );
          } else {
            throw pe; // We're confused!? Just catch this in the
FillServlet
          }
        }
      } else {  // We can do MORE with Python exceptions:
        int errorLineNo = pe.traceback.tb_lineno;              //
Awesome !
        if (exceptionName.equals("SystemExit")) { // SPyConsole uses
this for 'exit()'
          System.exit(0);
        } else {
          String errorValue = pe.value.toString(); // What can't
handle it? It was in each case below:
          String errorLocation; // = null;
          if (pageNumber == null) { // Flag for non-page errors:
FillRepeater, etc; pageSource is WHAT it is instead:
            errorLocation = "in " + pageSource; // Save space below...
          } else {
            errorLocation = "in '" + fillName + "' on page " +
pageNumber + ", line " + errorLineNo; // Save space below...
            if ( pageSource != null ) {
              String errorLine = Strings.field( pageSource,
Chars.LF, errorLineNo );
              errorLocation += ": \"" + errorLine + "\"";
            }
          }
          if (exceptionName.equals("NameError")||
exceptionName.equals("AttributeError")) {
            errorList.add(new FillError("F", exceptionName + " " +
errorLocation + ": Variable " + errorValue + " has not been defined"));
          } else if (exceptionName.equals("ImportError")) {
            errorList.add(new FillError("F", "Invalid Import" +
errorLocation, errorValue));
          } else if (exceptionName.equals ("TypeError")) {
            errorList.add(new FillError("F", "TypeError: Result is
not a valid type" + errorLocation, errorValue));
          } else if (exceptionName.equals("ZeroDivisionError")) {
            errorList.add(new FillError("W", "ZeroDivisionError:
Cannot divide by zero " + errorLocation, errorValue));
          } else {
            errorList.add(new FillError("F", exceptionName + ":
unhandled PyException " + errorLocation, errorValue));
          }
          if (d.level >= 2) { // Comment this for error debugging ?
            pe.printStackTrace();
          }
        }
      }
    } else {     // User-defined exception, 'type' and 'value' are
'PyString's
      String exceptionName = (pe.type).toString();
      //if (! exceptionName.equals("FatalError")) {  // Fatals have
already been added to 'errorList'...
      PyObject value = pe.value;
      String message = "";
      if (value == Py.None) {
        if ( exceptionName.charAt(1) == ':' ) {  //
'<type>:<message>' format
          message = exceptionName.substring(2);
          exceptionName = exceptionName.substring(0, 1);
        }
      } else {
        message = value.toString();
      }
      errorList.add(new FillError("F", "'" + fillName + "', page " +
pageNumber + ": " + exceptionName, message ) );
      d.msg(4, "E", "Fatal error: " + exceptionName + ":" + message);
    }
  }

%< ------------------------------


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Jython-users mailing list
Jython-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jython-users