diff --git a/src/helma/framework/core/Application.java b/src/helma/framework/core/Application.java index aebe1f41..211dced0 100644 --- a/src/helma/framework/core/Application.java +++ b/src/helma/framework/core/Application.java @@ -1366,13 +1366,7 @@ public final class Application implements Runnable { if (eventLog == null) { eventLog = getLogger(eventLogName); } - if ("true".equalsIgnoreCase(props.getProperty("jsStackTrace"))) { - Exception jsx = new RuntimeException(error); - StackUtils.setJavaScriptStack(error, jsx); - eventLog.error(msg, jsx); - } else { - eventLog.error(msg, error); - } + eventLog.error(msg, error); } /** @@ -1382,7 +1376,6 @@ public final class Application implements Runnable { if (eventLog == null) { eventLog = getLogger(eventLogName); } - eventLog.error(msg); } diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index 5f0ef727..3a4f02f4 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -544,10 +544,6 @@ public final class RequestEvaluator implements Runnable { error = "Unspecified error"; } - if (x instanceof ScriptingException) { - x = ((ScriptingException) x).getWrappedException(); - } - app.logError(txname + ": " + error, x); if (req.isXmlRpc()) { diff --git a/src/helma/framework/core/Skin.java b/src/helma/framework/core/Skin.java index b2d0de44..259335cf 100644 --- a/src/helma/framework/core/Skin.java +++ b/src/helma/framework/core/Skin.java @@ -581,10 +581,6 @@ public final class Skin { msg = new StringBuffer("Macro error in ").append(fullName) .append(": ").append(msg).toString(); reval.getResponse().write(" [" + msg + "] "); - // for ScriptingExceptions get the original exception - if (x instanceof ScriptingException) { - x = ((ScriptingException) x).getWrappedException(); - } app.logError(msg, x); } } diff --git a/src/helma/scripting/ScriptingException.java b/src/helma/scripting/ScriptingException.java index 5af73019..f70c12d0 100644 --- a/src/helma/scripting/ScriptingException.java +++ b/src/helma/scripting/ScriptingException.java @@ -16,6 +16,8 @@ package helma.scripting; +import java.util.List; +import java.util.ArrayList; import java.io.PrintStream; import java.io.PrintWriter; @@ -24,23 +26,122 @@ import java.io.PrintWriter; */ public class ScriptingException extends Exception { - // original exception that caused this ScriptingException to be thrown. - Exception wrapped; - /** * Construct a ScriptingException given an error message and wrapped exception. + * @param message the message + * @param cause the original exception */ - public ScriptingException(String msg, Exception wrapped) { - super(msg); - this.wrapped = wrapped; + public ScriptingException(String message, Throwable cause) { + super(message, cause); + setScriptStack(cause); } /** - * Get the original exception that caused this exception to be thrown. - * - * @return the wrapped exception + * Extract the JavaScript stack trace element from the source exception + * and copy them over to the target exception. + * @param cause the original exception */ - public Exception getWrappedException() { - return wrapped; + private void setScriptStack(Throwable cause) { + List list = new ArrayList(); + StackTraceElement[] stack = cause.getStackTrace(); + for (int i = 0; i < stack.length; i++) { + StackTraceElement e = stack[i]; + String name = e.getFileName(); + if (e.getLineNumber() > -1 && + (name.endsWith(".js") || name.endsWith(".hac"))) { + list.add(e); + } + } + setStackTrace((StackTraceElement[]) list.toArray(new StackTraceElement[list.size()])); } + + + /* + * Adaption from Throwable.printStackTrace() to only print Script file stack elements. + */ + public void printStackTrace(PrintStream s) { + synchronized (s) { + s.println(this); + StackTraceElement[] trace = getStackTrace(); + for (int i=0; i < trace.length; i++) + s.println("\tat " + trace[i].getFileName() + ":" + + trace[i].getLineNumber()); + Throwable ourCause = getCause(); + 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. + */ + public void printStackTrace(PrintWriter s) { + synchronized (s) { + s.println(this); + StackTraceElement[] trace = getStackTrace(); + for (int i=0; i < trace.length; i++) + s.println("\tat " + trace[i].getFileName() + ":" + + trace[i].getLineNumber()); + Throwable ourCause = getCause(); + 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); + } + } diff --git a/src/helma/util/StackUtils.java b/src/helma/util/StackUtils.java deleted file mode 100644 index 9106af14..00000000 --- a/src/helma/util/StackUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2006 Hannes Wallnoefer - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package helma.util; - -import java.util.List; -import java.util.ArrayList; - -/** - * Utility class to extract pure JavaScript stack trace from Java exceptions - */ -public class StackUtils { - - /** - * Extract the JavaScript stack trace element from the source exception - * and copy them over to the target exception. - * @param source the source exception - * @param target the target excepiton - */ - public static void setJavaScriptStack(Throwable source, Throwable target) { - List list = new ArrayList(); - StackTraceElement[] stack = source.getStackTrace(); - for (int i = 0; i < stack.length; i++) { - StackTraceElement e = stack[i]; - String name = e.getFileName(); - if (e.getLineNumber() > -1 && - (name.endsWith(".js") || name.endsWith(".hac"))) { - list.add(e); - } - } - target.setStackTrace((StackTraceElement[]) list.toArray(new StackTraceElement[list.size()])); - } - -}