* Previous solution didn't work with Rhino running in interpreter mode. Provide a
hook in RhinoException to make JS stack traces work with any optimization mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=363058
This commit is contained in:
parent
f3ce79f6c4
commit
b210d5cd11
1 changed files with 31 additions and 85 deletions
|
@ -16,16 +16,22 @@
|
||||||
|
|
||||||
package helma.scripting;
|
package helma.scripting;
|
||||||
|
|
||||||
import java.util.List;
|
import org.mozilla.javascript.RhinoException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base class for exceptions thrown by Helma scripting package
|
* The base class for wrapped exceptions thrown by invocation of the scripting engine.
|
||||||
|
* If the wrapped exception is a RhinoException, the script stack trace will be
|
||||||
|
* prepended to the actual java stack trace in stack dumps.
|
||||||
*/
|
*/
|
||||||
public class ScriptingException extends Exception {
|
public class ScriptingException extends Exception {
|
||||||
|
|
||||||
|
String scriptStack = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a ScriptingException given an error message and wrapped exception.
|
* Construct a ScriptingException given an error message and wrapped exception.
|
||||||
* @param message the message
|
* @param message the message
|
||||||
|
@ -42,17 +48,16 @@ public class ScriptingException extends Exception {
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
*/
|
*/
|
||||||
private void setScriptStack(Throwable cause) {
|
private void setScriptStack(Throwable cause) {
|
||||||
List list = new ArrayList();
|
if (cause instanceof RhinoException) {
|
||||||
StackTraceElement[] stack = cause.getStackTrace();
|
FilenameFilter filter = new FilenameFilter() {
|
||||||
for (int i = 0; i < stack.length; i++) {
|
public boolean accept(File dir, String name) {
|
||||||
StackTraceElement e = stack[i];
|
return name.endsWith(".js") ||
|
||||||
String name = e.getFileName();
|
name.endsWith(".hac") ||
|
||||||
if (e.getLineNumber() > -1 &&
|
name.endsWith(".hsp");
|
||||||
(name.endsWith(".js") || name.endsWith(".hac"))) {
|
}
|
||||||
list.add(e);
|
};
|
||||||
}
|
scriptStack = ((RhinoException) cause).getScriptStackTrace(filter);
|
||||||
}
|
}
|
||||||
setStackTrace((StackTraceElement[]) list.toArray(new StackTraceElement[list.size()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,87 +66,28 @@ public class ScriptingException extends Exception {
|
||||||
*/
|
*/
|
||||||
public void printStackTrace(PrintStream s) {
|
public void printStackTrace(PrintStream s) {
|
||||||
synchronized (s) {
|
synchronized (s) {
|
||||||
s.println(this);
|
if (scriptStack != null) {
|
||||||
StackTraceElement[] trace = getStackTrace();
|
s.println(this);
|
||||||
for (int i=0; i < trace.length; i++)
|
s.print(scriptStack);
|
||||||
s.println("\tat " + trace[i].getFileName() + ":" +
|
s.print("Full trace: ");
|
||||||
trace[i].getLineNumber());
|
}
|
||||||
Throwable ourCause = getCause();
|
getCause().printStackTrace(s);
|
||||||
if (ourCause != null)
|
|
||||||
printStackTraceAsCause(ourCause, s, trace);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Adaption from Throwable.printTraceAsCause() to be callable from this class.
|
|
||||||
*/
|
|
||||||
private static void printStackTraceAsCause(Throwable t, PrintStream s,
|
|
||||||
StackTraceElement[] causedTrace)
|
|
||||||
{
|
|
||||||
// assert Thread.holdsLock(s);
|
|
||||||
|
|
||||||
// Compute number of frames in common between this and caused
|
|
||||||
StackTraceElement[] trace = t.getStackTrace();
|
|
||||||
int m = trace.length-1, n = causedTrace.length-1;
|
|
||||||
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
|
|
||||||
m--; n--;
|
|
||||||
}
|
|
||||||
int framesInCommon = trace.length - 1 - m;
|
|
||||||
|
|
||||||
s.println("Caused by: " + t);
|
|
||||||
for (int i=0; i <= m; i++)
|
|
||||||
s.println("\tat " + trace[i]);
|
|
||||||
if (framesInCommon != 0)
|
|
||||||
s.println("\t... " + framesInCommon + " more");
|
|
||||||
|
|
||||||
// Recurse if t has a cause
|
|
||||||
Throwable theCause = t.getCause();
|
|
||||||
if (theCause != null)
|
|
||||||
printStackTraceAsCause(theCause, s, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adaption from Throwable.printStackTrace() to only print Script file stack elements.
|
* Adaption from Throwable.printStackTrace() to only print Script file stack elements.
|
||||||
*/
|
*/
|
||||||
public void printStackTrace(PrintWriter s) {
|
public void printStackTrace(PrintWriter s) {
|
||||||
synchronized (s) {
|
synchronized (s) {
|
||||||
s.println(this);
|
if (scriptStack != null) {
|
||||||
StackTraceElement[] trace = getStackTrace();
|
s.println(this);
|
||||||
for (int i=0; i < trace.length; i++)
|
s.print(scriptStack);
|
||||||
s.println("\tat " + trace[i].getFileName() + ":" +
|
s.print("Full trace: ");
|
||||||
trace[i].getLineNumber());
|
}
|
||||||
Throwable ourCause = getCause();
|
getCause().printStackTrace(s);
|
||||||
if (ourCause != null)
|
|
||||||
printStackTraceAsCause(ourCause, s, trace);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
}
|
||||||
* Adaption from Throwable.printTraceAsCause() to be callable from this class.
|
|
||||||
*/
|
|
||||||
private static void printStackTraceAsCause(Throwable t, PrintWriter s,
|
|
||||||
StackTraceElement[] causedTrace)
|
|
||||||
{
|
|
||||||
// assert Thread.holdsLock(s);
|
|
||||||
|
|
||||||
// Compute number of frames in common between this and caused
|
|
||||||
StackTraceElement[] trace = t.getStackTrace();
|
|
||||||
int m = trace.length-1, n = causedTrace.length-1;
|
|
||||||
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
|
|
||||||
m--; n--;
|
|
||||||
}
|
|
||||||
int framesInCommon = trace.length - 1 - m;
|
|
||||||
|
|
||||||
s.println("Caused by: " + t);
|
|
||||||
for (int i=0; i <= m; i++)
|
|
||||||
s.println("\tat " + trace[i]);
|
|
||||||
if (framesInCommon != 0)
|
|
||||||
s.println("\t... " + framesInCommon + " more");
|
|
||||||
|
|
||||||
// Recurse if t has a cause
|
|
||||||
Throwable theCause = t.getCause();
|
|
||||||
if (theCause != null)
|
|
||||||
printStackTraceAsCause(theCause, s, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue