Closed Bug 290034 Opened 21 years ago Closed 21 years ago

Cannot catch in JavaScript the original exception thrown by a host object implemented in Java (ScriptableObject subclass)

Categories

(Rhino Graveyard :: Core, defect)

x86
Windows XP
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: fernando.olcoz, Assigned: igor)

Details

Attachments

(2 files, 1 obsolete file)

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Build Identifier: It seems there is an inconsistent behaviour between an Object implemented in JavaScript and a host object implemented in Java when it comes to throwing exceptions. ¿What is the contract a Java host object must honor in order to simulate the JS "throw" keyword and being catched in JS "unmodified"? In 1.5R5, it worked throwing a JavaScriptException(), but in 1.5R6 the JavaScriptException is placed inside a WrappedException. Reproducible: Always Steps to Reproduce: 1.Consider the following script: // examples/problem-ok.js function JSCounter(n) { this.n = n; this.count = function() { if (n > 100) { throw java.lang.IllegalStateException("Greater than 100"); } return n++; }; } var c = new JSCounter(100); try { print(c.count()); print(c.count()); } catch (e) { print(e); if (e.javaException) { // NEVER ENTERS HERE print(e.javaException); } } Executing the script above produces the following, expected, output: js> load("examples/problem-ok.js") 100 java.lang.IllegalStateException: Greater than 100 2.Create a modified version of the supplied Counter host object that throws an exception when the count exceeds the 100 threshold: // Counter.java // ... public int jsGet_count() { if (count > 100) { throw new IllegalStateException("Greater than 100"); } return count++; } // ... 3.Run the following script, that uses the host object above: // examples/problem.js defineClass("Counter"); var c = new Counter(100); try { print(c.count); print(c.count); } catch (e) { print(e); if (e.javaException) { // ALWAYS ENTERS HERE print(e.javaException); } } 4.Running the above script yields the following result: js> load("examples/problem.js") 100 JavaException: java.lang.IllegalStateException: Greater than 100 java.lang.IllegalStateException: Greater than 100 Actual Results: The host object implemented in Java is unable to reproduce the "throw" keyword behaviour. Expected Results: There should be some way to write a host object in Java with members able to mimic the JS throw keyword.
Attached file Proposed change to ScriptRuntime.java (obsolete) —
This proposed change works for me: public static Scriptable newCatchScope(Throwable t, Scriptable lastCatchScope, String exceptionName, Context cx, Scriptable scope) { Object obj; boolean cacheObj; // *** BEGIN // FO: Check whether t is a WrappedException that // contains a JavaScriptException; if so, unwrap if (t instanceof WrappedException) { Throwable innerExc = ((WrappedException)t).getWrappedException(); if (innerExc instanceof JavaScriptException) { t = innerExc; } } // *** END getObj: // rest of method unchanged
An approach that works for me is: 1. Host objects which wish to mimic the "throw" keyword behaviour in any of its members throw a JavaScriptException(originalException). 2. ScriptRuntime.newCatchScope(...) checks the passed Throwable is a WrappedException wrapping a JavaScriptException. In that case unwraps the JavaScriptException and proceeds as usual.
Attachment #180479 - Attachment is obsolete: true
I committed the fix
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: