Reorganization of Java and JavaScript exception iteraction. See http://bugzilla.mozilla.org/show_bug.cgi?id=210605 for details.
git-svn-id: svn://10.0.0.236/trunk@144384 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -84,15 +84,11 @@ public class Delegator implements Function {
|
||||
*/
|
||||
protected Delegator newInstance()
|
||||
{
|
||||
Exception ex;
|
||||
try {
|
||||
return (Delegator)this.getClass().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
ex = e;
|
||||
} catch (IllegalAccessException e) {
|
||||
ex = e;
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
throw WrappedException.wrapException(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -413,22 +413,15 @@ public class FunctionObject extends BaseFunction {
|
||||
if (method == null) Context.codeBug();
|
||||
try {
|
||||
result = invoker.invoke(thisObj, invokeArgs);
|
||||
} catch (Exception e) {
|
||||
throw JavaScriptException.wrapException(cx, scope, e);
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
result = (method == null) ? ctor.newInstance(invokeArgs)
|
||||
: method.invoke(thisObj, invokeArgs);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw JavaScriptException.wrapException(cx, scope, e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
}
|
||||
return hasVoidReturn ? Undefined.instance : result;
|
||||
@@ -447,10 +440,8 @@ public class FunctionObject extends BaseFunction {
|
||||
Scriptable result;
|
||||
try {
|
||||
result = (Scriptable) method.getDeclaringClass().newInstance();
|
||||
} catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
|
||||
result.setPrototype(getClassPrototype());
|
||||
@@ -459,7 +450,6 @@ public class FunctionObject extends BaseFunction {
|
||||
}
|
||||
|
||||
private Object callVarargs(Context cx, Scriptable thisObj, Object[] args)
|
||||
throws JavaScriptException
|
||||
{
|
||||
try {
|
||||
if (parmsLength == VARARGS_METHOD) {
|
||||
@@ -474,21 +464,8 @@ public class FunctionObject extends BaseFunction {
|
||||
? ctor.newInstance(invokeArgs)
|
||||
: method.invoke(null, invokeArgs);
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Throwable target = e.getTargetException();
|
||||
if (target instanceof EvaluatorException)
|
||||
throw (EvaluatorException) target;
|
||||
if (target instanceof EcmaError)
|
||||
throw (EcmaError) target;
|
||||
Scriptable scope = thisObj == null ? this : thisObj;
|
||||
throw JavaScriptException.wrapException(cx, scope, target);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1712,23 +1712,18 @@ public class Interpreter {
|
||||
|
||||
final int SCRIPT_CAN_CATCH = 0, ONLY_FINALLY = 1, OTHER = 2;
|
||||
int exType;
|
||||
for (;;) {
|
||||
if (javaException instanceof JavaScriptException) {
|
||||
exType = SCRIPT_CAN_CATCH;
|
||||
} else if (javaException instanceof EcmaError) {
|
||||
// an offical ECMA error object,
|
||||
exType = SCRIPT_CAN_CATCH;
|
||||
} else if (javaException instanceof WrappedException) {
|
||||
WrappedException wex = (WrappedException)javaException;
|
||||
javaException = wex.getWrappedException();
|
||||
continue;
|
||||
} else if (javaException instanceof RuntimeException) {
|
||||
exType = ONLY_FINALLY;
|
||||
} else {
|
||||
// Error instance
|
||||
exType = OTHER;
|
||||
}
|
||||
break;
|
||||
if (javaException instanceof JavaScriptException) {
|
||||
exType = SCRIPT_CAN_CATCH;
|
||||
} else if (javaException instanceof EcmaError) {
|
||||
// an offical ECMA error object,
|
||||
exType = SCRIPT_CAN_CATCH;
|
||||
} else if (javaException instanceof WrappedException) {
|
||||
exType = SCRIPT_CAN_CATCH;
|
||||
} else if (javaException instanceof RuntimeException) {
|
||||
exType = ONLY_FINALLY;
|
||||
} else {
|
||||
// Error instance
|
||||
exType = OTHER;
|
||||
}
|
||||
|
||||
if (exType != OTHER) {
|
||||
|
||||
@@ -141,7 +141,7 @@ public final class JavaAdapter
|
||||
newInstance(ctorArgs);
|
||||
return getAdapterSelf(adapterClass, adapter);
|
||||
} catch (Exception ex) {
|
||||
throw WrappedException.wrapException(ex);
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ public final class JavaAdapter
|
||||
}
|
||||
return ScriptRuntime.call(cx, fun, thisObj, args, object);
|
||||
} catch (JavaScriptException ex) {
|
||||
throw WrappedException.wrapException(ex);
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
|
||||
@@ -107,14 +107,8 @@ class JavaMembers {
|
||||
rval = field.get(isStatic ? null : javaObject);
|
||||
type = field.getType();
|
||||
}
|
||||
} catch (IllegalAccessException accEx) {
|
||||
throw new RuntimeException("unexpected IllegalAccessException "+
|
||||
"accessing Java field");
|
||||
} catch (InvocationTargetException e) {
|
||||
// Since JavaScriptException is a checked exception, must
|
||||
// wrap the JavaScriptException in a WrappedException
|
||||
throw WrappedException.wrapException(
|
||||
JavaScriptException.wrapException(cx, scope, e));
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
// Need to wrap the object before we return it.
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
@@ -221,13 +215,8 @@ class JavaMembers {
|
||||
Object[] args = { NativeJavaObject.coerceType(types[0], value,
|
||||
true) };
|
||||
method.invoke(javaObject, args);
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
throw new RuntimeException("unexpected IllegalAccessException " +
|
||||
"accessing Java field");
|
||||
} catch (InvocationTargetException e) {
|
||||
throw WrappedException.wrapException(
|
||||
JavaScriptException.wrapException(
|
||||
Context.getContext(), scope, e));
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -38,92 +38,32 @@
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Java reflection of JavaScript exceptions. (Possibly wrapping a Java exception.)
|
||||
* Java reflection of JavaScript exceptions.
|
||||
* Instances of this class are thrown by the JavaScript 'throw' keyword.
|
||||
*
|
||||
* @author Mike McCabe
|
||||
*/
|
||||
public class JavaScriptException extends Exception {
|
||||
public class JavaScriptException extends Exception
|
||||
{
|
||||
/**
|
||||
* <p>Pointer to initCause() method of Throwable.
|
||||
* If this method does not exist,
|
||||
* (i.e. we're running on something earlier than Java 1.4), the pointer will
|
||||
* be null.</p>
|
||||
*/
|
||||
private static Method initCauseMethod = null;
|
||||
|
||||
static {
|
||||
// Are we running on a JDK 1.4 or later system?
|
||||
try {
|
||||
Class ThrowableClass = ScriptRuntime.classOrNull(
|
||||
"java.lang.Throwable");
|
||||
initCauseMethod = ThrowableClass.getMethod("initCause",
|
||||
new Class[]{ThrowableClass});
|
||||
} catch (Exception ex) {
|
||||
// Assume any exceptions means the method does not exist.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JavaScript exception wrapping the given JavaScript value.
|
||||
*
|
||||
* Instances of this class are thrown by the JavaScript 'throw' keyword.
|
||||
* Create a JavaScript exception wrapping the given JavaScript value
|
||||
*
|
||||
* @param value the JavaScript value thrown.
|
||||
*/
|
||||
public JavaScriptException(Object value) {
|
||||
public JavaScriptException(Object value)
|
||||
{
|
||||
super(ScriptRuntime.toString(value));
|
||||
if (value instanceof Throwable && initCauseMethod != null) {
|
||||
try {
|
||||
initCauseMethod.invoke(this, new Object[] {value});
|
||||
} catch (Exception e) {
|
||||
// Ignore any exceptions
|
||||
}
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
static JavaScriptException wrapException(Context cx, Scriptable scope,
|
||||
Throwable exn)
|
||||
{
|
||||
if (exn instanceof InvocationTargetException)
|
||||
exn = ((InvocationTargetException)exn).getTargetException();
|
||||
if (exn instanceof JavaScriptException)
|
||||
return (JavaScriptException)exn;
|
||||
Object wrapper = cx.getWrapFactory().
|
||||
wrap(cx, scope, exn, Throwable.class);
|
||||
return new JavaScriptException(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception value originally thrown. This may be a
|
||||
* JavaScript value (null, undefined, Boolean, Number, String,
|
||||
* Scriptable or Function) or a Java exception value thrown from a
|
||||
* host object or from Java called through LiveConnect.
|
||||
*
|
||||
* @return the value wrapped by this exception
|
||||
*/
|
||||
public Object getValue() {
|
||||
if (value != null && value instanceof Wrapper)
|
||||
// this will also catch NativeStrings...
|
||||
return ((Wrapper)value).unwrap();
|
||||
else
|
||||
return value;
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The JavaScript exception value. This value is not
|
||||
* intended for general use; if the JavaScriptException wraps a
|
||||
* Java exception, getScriptableValue may return a Scriptable
|
||||
* wrapping the original Java exception object.
|
||||
*
|
||||
* We would prefer to go through a getter to encapsulate the value,
|
||||
* however that causes the bizarre error "nanosecond timeout value
|
||||
* out of range" on the MS JVM.
|
||||
* @serial
|
||||
*/
|
||||
Object value;
|
||||
private Object value;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class LazilyLoadedCtor {
|
||||
ScriptableObject.DONTENUM);
|
||||
}
|
||||
catch (PropertyException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
throw ScriptRuntime.throwAsUncheckedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,24 +85,10 @@ public final class LazilyLoadedCtor {
|
||||
try {
|
||||
ScriptableObject.defineClass(obj, cl, sealed);
|
||||
isReplaced = true;
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (ClassDefinitionException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (PropertyException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
}
|
||||
catch (SecurityException ex) {
|
||||
} catch (SecurityException ex) {
|
||||
removeOnError = true;
|
||||
} catch (Exception e) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(e);
|
||||
}
|
||||
}
|
||||
if (removeOnError) {
|
||||
|
||||
@@ -115,7 +115,7 @@ public class NativeFunction extends BaseFunction {
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
// Wrap the rest of exceptions including possible SecurityException
|
||||
throw WrappedException.wrapException(ex);
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,11 +235,11 @@ public class NativeJavaClass extends NativeJavaObject implements Function {
|
||||
String ctorString = ctor.toString();
|
||||
throw Context.reportRuntimeError3(
|
||||
"msg.bad.ctor.sig", argEx.getMessage(), ctorString, signature);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw JavaScriptException.wrapException(cx, scope, e);
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.java.internal.private", accessEx.getMessage());
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
// we need to force this to be wrapped, because construct _has_
|
||||
// to return a scriptable
|
||||
|
||||
@@ -228,50 +228,49 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
||||
}
|
||||
javaObject = ((Wrapper) o).unwrap();
|
||||
}
|
||||
try {
|
||||
if (debug) {
|
||||
printDebug("Calling ", meth, args);
|
||||
}
|
||||
if (debug) {
|
||||
printDebug("Calling ", meth, args);
|
||||
}
|
||||
|
||||
Object retval;
|
||||
Object retval;
|
||||
try {
|
||||
try {
|
||||
retval = meth.invoke(javaObject, args);
|
||||
} catch (IllegalAccessException e) {
|
||||
retval = retryIllegalAccessInvoke(meth, javaObject, args, e);
|
||||
}
|
||||
Class staticType = meth.getReturnType();
|
||||
|
||||
if (debug) {
|
||||
Class actualType = (retval == null) ? null
|
||||
: retval.getClass();
|
||||
System.err.println(" ----- Returned " + retval +
|
||||
" actual = " + actualType +
|
||||
" expect = " + staticType);
|
||||
}
|
||||
|
||||
Object wrapped = cx.getWrapFactory().wrap(cx, scope,
|
||||
retval, staticType);
|
||||
|
||||
if (debug) {
|
||||
Class actualType = (wrapped == null) ? null
|
||||
: wrapped.getClass();
|
||||
System.err.println(" ----- Wrapped as " + wrapped +
|
||||
" class = " + actualType);
|
||||
}
|
||||
|
||||
if (wrapped == Undefined.instance)
|
||||
return wrapped;
|
||||
if (wrapped == null && staticType == Void.TYPE)
|
||||
return Undefined.instance;
|
||||
return wrapped;
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
throw Context.reportRuntimeError(
|
||||
"While attempting to call \"" + meth.getName() +
|
||||
"\" in class \"" + meth.getDeclaringClass().getName() +
|
||||
"\" receieved " + accessEx.toString());
|
||||
} catch (InvocationTargetException e) {
|
||||
throw JavaScriptException.wrapException(cx, scope, e);
|
||||
} catch (Exception ex) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
}
|
||||
Class staticType = meth.getReturnType();
|
||||
|
||||
if (debug) {
|
||||
Class actualType = (retval == null) ? null
|
||||
: retval.getClass();
|
||||
System.err.println(" ----- Returned " + retval +
|
||||
" actual = " + actualType +
|
||||
" expect = " + staticType);
|
||||
}
|
||||
|
||||
Object wrapped = cx.getWrapFactory().wrap(cx, scope,
|
||||
retval, staticType);
|
||||
if (debug) {
|
||||
Class actualType = (wrapped == null) ? null
|
||||
: wrapped.getClass();
|
||||
System.err.println(" ----- Wrapped as " + wrapped +
|
||||
" class = " + actualType);
|
||||
}
|
||||
|
||||
if (wrapped == Undefined.instance)
|
||||
return wrapped;
|
||||
if (wrapped == null && staticType == Void.TYPE)
|
||||
return Undefined.instance;
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
static Object retryIllegalAccessInvoke(Method method, Object obj,
|
||||
@@ -321,7 +320,7 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
||||
|
||||
/**
|
||||
* Find the correct function to call given the set of methods
|
||||
* or constructors and the arguments.
|
||||
* or constructors and the arguments.
|
||||
* If no function can be found to call, return null.
|
||||
*/
|
||||
static Member findFunction(Member[] methodsOrCtors, Object[] args) {
|
||||
|
||||
@@ -699,52 +699,62 @@ public class ScriptRuntime {
|
||||
return (char)i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a JavaScriptException. Sleight of hand so that we don't
|
||||
* javadoc JavaScriptException.getRuntimeValue().
|
||||
*/
|
||||
public static Object unwrapJavaScriptException(JavaScriptException jse) {
|
||||
return jse.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a WrappedException. Unwrap a JavaScriptException and return
|
||||
* the value, otherwise rethrow.
|
||||
*/
|
||||
public static Object unwrapWrappedException(WrappedException we) {
|
||||
Throwable t = we.getWrappedException();
|
||||
if (t instanceof JavaScriptException)
|
||||
return ((JavaScriptException) t).value;
|
||||
throw we;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Java exceptions that JS can catch into an object the script
|
||||
* will see as the catch argument.
|
||||
*/
|
||||
public static Object getCatchObject(Context cx, Scriptable scope,
|
||||
Throwable exception)
|
||||
Throwable t)
|
||||
{
|
||||
Object catchObj;
|
||||
for (;;) {
|
||||
if (exception instanceof JavaScriptException) {
|
||||
catchObj = ScriptRuntime.unwrapJavaScriptException(
|
||||
(JavaScriptException)exception);
|
||||
} else if (exception instanceof EcmaError) {
|
||||
// an offical ECMA error object,
|
||||
catchObj = ((EcmaError)exception).getErrorObject();
|
||||
} else if (exception instanceof WrappedException) {
|
||||
WrappedException wex = (WrappedException)exception;
|
||||
exception = wex.getWrappedException();
|
||||
continue;
|
||||
} else {
|
||||
// catch can not be called with any other exceptions
|
||||
Context.codeBug();
|
||||
catchObj = null;
|
||||
if (t instanceof JavaScriptException) {
|
||||
return ((JavaScriptException)t).getValue();
|
||||
} else if (t instanceof EcmaError) {
|
||||
return ((EcmaError)t).getErrorObject();
|
||||
} else {
|
||||
if (!(t instanceof WrappedException)) Context.codeBug();
|
||||
do {
|
||||
t = ((WrappedException)t).getWrappedException();
|
||||
} while (t instanceof WrappedException);
|
||||
if (t instanceof JavaScriptException) {
|
||||
return ((JavaScriptException)t).getValue();
|
||||
} else if (t instanceof EcmaError) {
|
||||
return ((EcmaError)t).getErrorObject();
|
||||
}
|
||||
break;
|
||||
return cx.getWrapFactory().wrap(cx, scope, t, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rethrow exception wrapped into {@link WrappedException} unless
|
||||
* the exception is an instance of {@link EvaluatorExceptions},
|
||||
* {@link EcmaError} or java.lang.Error which are rethrown as-is.
|
||||
* <p>
|
||||
* Instances of java.lang.reflect.InvocationTargetExceptions are treated
|
||||
* specially. They are unwrapped and throwAsUncheckedException is applied
|
||||
* recursively to its target.
|
||||
* <p>
|
||||
* This method always throws an exception, its return value is provided
|
||||
* only for convenience to allow a usage like:
|
||||
* <pre>
|
||||
* throw ScriptRuntime.throwAsUncheckedException(ex);
|
||||
* </pre>
|
||||
* to indicate that code after the method is unreachable.
|
||||
*/
|
||||
public static RuntimeException throwAsUncheckedException(Throwable e)
|
||||
{
|
||||
while ((e instanceof InvocationTargetException)) {
|
||||
e = ((InvocationTargetException) e).getTargetException();
|
||||
}
|
||||
return catchObj;
|
||||
if (e instanceof Error) {
|
||||
throw (Error)e;
|
||||
}
|
||||
if (e instanceof EvaluatorException) {
|
||||
throw (EvaluatorException)e;
|
||||
}
|
||||
if (e instanceof EcmaError) {
|
||||
throw (EcmaError)e;
|
||||
}
|
||||
throw new WrappedException(e);
|
||||
}
|
||||
|
||||
public static Object getProp(Object obj, String id, Scriptable scope) {
|
||||
|
||||
@@ -206,10 +206,8 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||
|
||||
try {
|
||||
return slot.getter.invoke(getterThis, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (Exception e) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,10 +306,8 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||
|
||||
try {
|
||||
setterResult = slot.setter.invoke(setterThis, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw WrappedException.wrapException(e);
|
||||
} catch (Exception e) {
|
||||
throw ScriptRuntime.throwAsUncheckedException(e);
|
||||
}
|
||||
|
||||
if (slot.setterReturnsValue) {
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
package org.mozilla.javascript;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A wrapper for runtime exceptions.
|
||||
@@ -44,16 +45,45 @@ import java.lang.reflect.InvocationTargetException;
|
||||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public class WrappedException extends EvaluatorException implements Wrapper {
|
||||
public class WrappedException extends EvaluatorException
|
||||
{
|
||||
|
||||
/**
|
||||
* <p>Pointer to initCause() method of Throwable.
|
||||
* If this method does not exist,
|
||||
* (i.e. we're running on something earlier than Java 1.4), the pointer will
|
||||
* be null.</p>
|
||||
*/
|
||||
private static Method initCauseMethod = null;
|
||||
|
||||
static {
|
||||
// Are we running on a JDK 1.4 or later system?
|
||||
try {
|
||||
Class ThrowableClass = ScriptRuntime.classOrNull(
|
||||
"java.lang.Throwable");
|
||||
initCauseMethod = ThrowableClass.getMethod("initCause",
|
||||
new Class[]{ThrowableClass});
|
||||
} catch (Exception ex) {
|
||||
// Assume any exceptions means the method does not exist.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new exception wrapped around an existing exception.
|
||||
*
|
||||
* @param exception the exception to wrap
|
||||
*/
|
||||
public WrappedException(Throwable exception) {
|
||||
public WrappedException(Throwable exception)
|
||||
{
|
||||
super(exception.getMessage());
|
||||
this.exception = exception;
|
||||
if (initCauseMethod != null) {
|
||||
try {
|
||||
initCauseMethod.invoke(this, new Object[] {exception});
|
||||
} catch (Exception e) {
|
||||
// Ignore any exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +91,8 @@ public class WrappedException extends EvaluatorException implements Wrapper {
|
||||
*
|
||||
* Delegates to the wrapped exception.
|
||||
*/
|
||||
public String getMessage() {
|
||||
public String getMessage()
|
||||
{
|
||||
return "WrappedException of " + exception.toString();
|
||||
}
|
||||
|
||||
@@ -70,7 +101,8 @@ public class WrappedException extends EvaluatorException implements Wrapper {
|
||||
*
|
||||
* Delegates to the wrapped exception.
|
||||
*/
|
||||
public String getLocalizedMessage() {
|
||||
public String getLocalizedMessage()
|
||||
{
|
||||
return "WrappedException of " + exception.getLocalizedMessage();
|
||||
}
|
||||
|
||||
@@ -80,36 +112,10 @@ public class WrappedException extends EvaluatorException implements Wrapper {
|
||||
* @return the exception that was presented as a argument to the
|
||||
* constructor when this object was created
|
||||
*/
|
||||
public Throwable getWrappedException() {
|
||||
public Throwable getWrappedException()
|
||||
{
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wrapped exception.
|
||||
*
|
||||
* @return the exception that was presented as a argument to the
|
||||
* constructor when this object was created
|
||||
*/
|
||||
public Object unwrap() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an exception.
|
||||
*
|
||||
* Provides special cases for EvaluatorExceptions (which are returned
|
||||
* as-is), and InvocationTargetExceptions (which are unwrapped and
|
||||
* passed to a recursive call to wrapException).<p>
|
||||
*
|
||||
* Otherwise the exception is simply wrapped in a WrappedException.
|
||||
*/
|
||||
public static EvaluatorException wrapException(Throwable e) {
|
||||
if ((e instanceof InvocationTargetException))
|
||||
e = ((InvocationTargetException) e).getTargetException();
|
||||
if (e instanceof EvaluatorException)
|
||||
return (EvaluatorException) e;
|
||||
return new WrappedException(e);
|
||||
}
|
||||
|
||||
private Throwable exception;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class Codegen extends Interpreter {
|
||||
onlySave = true;
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
throw ScriptRuntime.throwAsUncheckedException(iox);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ public class Codegen extends Interpreter {
|
||||
onlySave = true;
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
throw ScriptRuntime.throwAsUncheckedException(iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2143,31 +2143,27 @@ public class Codegen extends Interpreter {
|
||||
aload(savedVariableObject);
|
||||
astore(variableObjectLocal);
|
||||
|
||||
aload(contextLocal);
|
||||
aload(variableObjectLocal);
|
||||
aload(exceptionObject);
|
||||
releaseWordLocal(exceptionObject);
|
||||
|
||||
// unwrap the exception...
|
||||
addScriptRuntimeInvoke(
|
||||
"getCatchObject",
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/Throwable;"
|
||||
+")Ljava/lang/Object;");
|
||||
|
||||
String exceptionName;
|
||||
|
||||
if (exceptionType == JAVASCRIPT_EXCEPTION) {
|
||||
// unwrap the exception...
|
||||
addScriptRuntimeInvoke(
|
||||
"unwrapJavaScriptException",
|
||||
"(Lorg/mozilla/javascript/JavaScriptException;"
|
||||
+")Ljava/lang/Object;");
|
||||
exceptionName = "org/mozilla/javascript/JavaScriptException";
|
||||
} else if (exceptionType == WRAPPED_EXCEPTION) {
|
||||
// unwrap the exception...
|
||||
addScriptRuntimeInvoke(
|
||||
"unwrapWrappedException",
|
||||
"(Lorg/mozilla/javascript/WrappedException;"
|
||||
+")Ljava/lang/Object;");
|
||||
exceptionName = "org/mozilla/javascript/WrappedException";
|
||||
} else {
|
||||
if (exceptionType != ECMAERROR_EXCEPTION) Context.codeBug();
|
||||
// unwrap the exception...
|
||||
addVirtualInvoke("org/mozilla/javascript/EcmaError",
|
||||
"getErrorObject",
|
||||
"()Lorg/mozilla/javascript/Scriptable;");
|
||||
exceptionName = "org/mozilla/javascript/EcmaError";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user