On Feb 22, 1:39 pm, [EMAIL PROTECTED] wrote:
> Hi Everyone,
>
> I noticed something today while trying to call some Java code that
> generates exceptions and catch them in a JS catch-block. It seems that
> an exception thrown from Java code that is called by JS code presents
> differently than an exception thrown directly by JS code, even if it
> is the same exception. This (unless I am mistaken) forces you to write
> code like the following:
>
> try {
>     // ... code that throws a FooException, maybe during a call into
> Java code, maybe not}
>
> catch(e if e instanceof FooException || e.javaException instanceof
> FooException) {
>     e = e.javaException || e
>
>     // code to deal with a FooException
>
> }
>
> while I think someone in this situation would much prefer to write:
>
> try {
>     // ... code that throws a FooException, maybe during a call into
> Java code, maybe not}
>
> catch(e if e instanceof FooException) {
>     // code to deal with a FooException
>
> }
>
> This is a pretty leaky abstraction. Is there some reason that a Java
> exception is wrapped differently based on whether it comes from actual
> Java code or not? To anyone trying to use Rhino as a general purpose
> application language that is interoperable with Java libraries this
> seems like a significant pitfall.
>
> Would the Rhino team be opposed to a context flag that changes the
> behavior of ScriptRuntime.newCatchScope to throw exceptions
> consistently no matter the language of origination? I would be glad to
> write the code myself if it stands some chance of being incorporated
> into the trunk.
>
> Thanks,
> Ben Reesman

This is the first draft of a patch I would propose:

*** mozilla/js/rhino/src/org/mozilla/javascript/Context.java
2008-02-08 11:15:59.000000000 -0800
--- mozilla-patched/js/rhino/src/org/mozilla/javascript/Context.java
2008-02-22 16:13:46.000000000 -0800
***************
*** 305,310 ****
--- 305,321 ----
       */
      public static final int FEATURE_ENHANCED_JAVA_ACCESS = 13;

+     /**
+      * Treats Java exceptions uniformly whether thrown from
JavaScript or Java.
+      * Specifically, ensures that a given conditional catch will
choose an exception
+      * for handling uniformly whether thrown from Java code or from
within an executing
+      * script.
+      * <p>
+      * Note that this feature is not yet included in Rhino.
+      * <p>
+      * By default [EMAIL PROTECTED] #hasFeature(int)} returns false.
+      */
+     public static final int FEATURE_UNIFORM_JAVA_EXCEPTIONS = 14;

      public static final String languageVersionProperty = "language
version";
      public static final String errorReporterProperty   = "error
reporter";
***************
*** 2034,2039 ****
--- 2045,2051 ----
       * @see #FEATURE_STRICT_MODE
       * @see #FEATURE_WARNING_AS_ERROR
       * @see #FEATURE_ENHANCED_JAVA_ACCESS
+      * @see #FEATURE_UNIFORM_JAVA_EXCEPTIONS
       */
      public boolean hasFeature(int featureIndex)
      {
diff -c -r mozilla/js/rhino/src/org/mozilla/javascript/
ScriptRuntime.java mozilla-patched/js/rhino/src/org/mozilla/javascript/
ScriptRuntime.java
*** mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java
2008-02-13 10:33:15.000000000 -0800
--- mozilla-patched/js/rhino/src/org/mozilla/javascript/
ScriptRuntime.java      2008-02-22 16:17:36.000000000 -0800
***************
*** 3139,3144 ****
--- 3139,3154 ----
          if (t instanceof JavaScriptException) {
              cacheObj = false;
              obj = ((JavaScriptException)t).getValue();
+         }
+         // this is not yet incorporated into the Rhino CVS. it is
enabled by the context flag
+         // FEATURE_UNIFORM_JAVA_EXCEPTIONS. the result of this is
that the thrown exception
+         // behaves exactly like the case above, i.e. that it was
thrown from JavaScript code.
+         // this allows you to have one 'catch' statement that
handles the exception no matter where
+         // it is from.
+         else if
(cx.hasFeature(Context.FEATURE_UNIFORM_JAVA_EXCEPTIONS) && t
instanceof WrappedException) {
+             cacheObj = false;
+             obj = ((WrappedException)t).unwrap();
+             obj = new NativeJavaObject(scope, obj, obj.getClass());
          } else {
              cacheObj = true;

Please let me know if this seems reasonable. I am interested to know
if it would be acceptable to set 'cacheObj' to true in this case. It
seems not but I'd love to know for sure.

Thanks,
Ben Reesman

_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to