Rethrown errors show the stacktrace of rethrowing, not their original stacktrace:



12 years ago
a month ago


(Reporter: dfabulich, Unassigned)





12 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20061025 Firefox/
Build Identifier: 1.6R5

Run this:

1 try {
2   throw new Error('urk');
3 } catch (e) {
4   throw e;
5 }

The JavaScriptException's stacktrace will report the JS line number as line 4 ("throw e") instead of line 2 where the exception was originally thrown.

This is because the exception, when created, knows nothing about its stacktrace at the time; this is only calculated once it comes time to .printStackTrace in the resulting JavaScriptException.  This bug is therefore related to enhancement bug 342807; a fix for 342807 would fix this nicely.

Reproducible: Always

Steps to Reproduce:
Create a file called "bug.js", containing this:

try {
  throw new Error('urk');
} catch (e) {
  throw e;

Load that file under the shell, with load('bug.js').
Actual Results:  
"bug.js", line 4: exception from uncaught JavaScript throw: [object Error]

Expected Results:  
"bug.js", line 2: exception from uncaught JavaScript throw: [object Error]

Comment 1

12 years ago
This is unfortunately true -- the mechanism of this is such that JavaScriptException is used as a means of transportation of the JS exception object (which can be any object) through the Rhino internals (and can additionally pop up in the top-level caller Java code as well). 

When a catch() block is encountered in the script, a new "catch(e)" scope is established, with JavaScriptException's getValue() being assigned to the "e" variable, and after that the JavaScriptException object is discarded, thus effectively forgetting the original stack trace. 

I'm not sure whether this is to be considered a bug -- after all, the ECMA standard does not define assignment of stack trace information with thrown objects (which, again, needn't be Error instances -- the "throw" statement can throw any object). "throw new Error" and "throw e" aren't any different, and Rhino always creates a new JavaScriptException when it implements the "throw" keyword. So I'll reassign the severity to "enhancement", and in spirit of that wait for possible ideas how to implement this.

I already thought about using a ThreadLocal with a WeakReference in JavaScriptException (JSE) to keep the last error object's associated JSE around in case error is rethrown, and then reuse that JSE. However, that'd get defeated if the catch block invoked further code that itself uses try/catch:

try {
  throw new Error("E1");
} catch(e1) {
  try {
    throw new Error("E2");
  catch(e2) {
  throw e1;

So, if you have a good idea, let me know.
Severity: normal → enhancement


12 years ago
Priority: -- → P5

Closing. Bug management is now done here:

Last Resolved: a month ago
Resolution: --- → INACTIVE
You need to log in before you can comment on or make changes to this bug.