Bug 518621 - JS_ReportErrorNumber ignores exception type for user-generated messages. r=mrbkap
authorDan Witte <dwitte@mozilla.com>
Tue, 15 Dec 2009 14:20:48 -0800
changeset 36234 760590721612581f266b32a4e1627d3c13644736
parent 36233 e0cb183375ddba959b895f45421de5bbe1804c4d
child 36235 227094a1e61391fefa2eb5c0485eb254280f9684
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs518621
milestone1.9.3a1pre
Bug 518621 - JS_ReportErrorNumber ignores exception type for user-generated messages. r=mrbkap
js/ctypes/ctypes.msg
js/src/jsapi.cpp
js/src/jscntxt.cpp
js/src/jsexn.cpp
js/src/jsexn.h
js/src/jsscan.cpp
--- a/js/ctypes/ctypes.msg
+++ b/js/ctypes/ctypes.msg
@@ -38,15 +38,10 @@
 
 /*
  * This is the jsctypes error message file.
  *
  * For syntax details, see js/src/js.msg.
  */
 
 MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, 0, JSEXN_NONE, NULL)
-MSG_DEF(CTYPESMSG_PLACEHOLDER_1, 1, 0, JSEXN_NONE, NULL)
-MSG_DEF(CTYPESMSG_PLACEHOLDER_2, 2, 0, JSEXN_NONE, NULL)
+MSG_DEF(CTYPESMSG_TYPE_ERROR,    1, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
 
-// This error has to be number 3 in order to be a TypeError,
-// due to a bug in the js engine.
-MSG_DEF(CTYPESMSG_TYPE_ERROR,    3, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
-
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5822,17 +5822,18 @@ JS_ErrorFromException(JSContext *cx, jsv
     CHECK_REQUEST(cx);
     return js_ErrorFromException(cx, v);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ThrowReportedError(JSContext *cx, const char *message,
                       JSErrorReport *reportp)
 {
-    return JS_IsRunning(cx) && js_ErrorToException(cx, message, reportp);
+    return JS_IsRunning(cx) &&
+           js_ErrorToException(cx, message, reportp, NULL, NULL);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ThrowStopIteration(JSContext *cx)
 {
     return js_ThrowStopIteration(cx);
 }
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1276,37 +1276,40 @@ MarkLocalRoots(JSTracer *trc, JSLocalRoo
         mark = JSVAL_TO_INT(lrc->roots[m]);
         if (m == 0)
             lrc = lrc->down;
     } while (n != 0);
     JS_ASSERT(!lrc);
 }
 
 static void
-ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
+ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
+            JSErrorCallback callback, void *userRef)
 {
     /*
      * Check the error report, and set a JavaScript-catchable exception
      * if the error is defined to have an associated exception.  If an
      * exception is thrown, then the JSREPORT_EXCEPTION flag will be set
      * on the error report, and exception-aware hosts should ignore it.
      */
     JS_ASSERT(reportp);
-    if (reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
+    if ((!callback || callback == js_GetErrorMessage) &&
+        reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
         reportp->flags |= JSREPORT_EXCEPTION;
 
     /*
      * Call the error reporter only if an exception wasn't raised.
      *
      * If an exception was raised, then we call the debugErrorHook
      * (if present) to give it a chance to see the error before it
      * propagates out of scope.  This is needed for compatability
      * with the old scheme.
      */
-    if (!JS_IsRunning(cx) || !js_ErrorToException(cx, message, reportp)) {
+    if (!JS_IsRunning(cx) ||
+        !js_ErrorToException(cx, message, reportp, callback, userRef)) {
         js_ReportErrorAgain(cx, message, reportp);
     } else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
         JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
         /* test local in case debugErrorHook changed on another thread */
         if (hook)
             hook(cx, message, reportp, cx->debugHooks->debugErrorHookData);
     }
 }
@@ -1452,17 +1455,17 @@ js_ReportErrorVA(JSContext *cx, uintN fl
     memset(&report, 0, sizeof (struct JSErrorReport));
     report.flags = flags;
     report.errorNumber = JSMSG_USER_DEFINED_ERROR;
     report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);
     PopulateReportBlame(cx, &report);
 
     warning = JSREPORT_IS_WARNING(report.flags);
 
-    ReportError(cx, message, &report);
+    ReportError(cx, message, &report, NULL, NULL);
     js_free(message);
     cx->free(ucmessage);
     return warning;
 }
 
 /*
  * The arguments from ap need to be packaged up into an array and stored
  * into the report struct.
@@ -1646,17 +1649,17 @@ js_ReportErrorNumberVA(JSContext *cx, ui
     report.errorNumber = errorNumber;
     PopulateReportBlame(cx, &report);
 
     if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
                                  &message, &report, charArgs, ap)) {
         return JS_FALSE;
     }
 
-    ReportError(cx, message, &report);
+    ReportError(cx, message, &report, callback, userRef);
 
     if (message)
         cx->free(message);
     if (report.messageArgs) {
         /*
          * js_ExpandErrorArguments owns its messageArgs only if it had to
          * inflate the arguments (from regular |char *|s).
          */
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -1099,17 +1099,18 @@ static struct exnname { char *name; char
 #define MSG_DEF(name, number, count, exception, format) \
     {#name, #exception},
 #include "js.msg"
 #undef MSG_DEF
 };
 #endif /* DEBUG */
 
 JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
+                    JSErrorCallback callback, void *userRef)
 {
     JSErrNum errorNumber;
     const JSErrorFormatString *errorString;
     JSExnType exn;
     jsval tv[4];
     JSTempValueRooter tvr;
     JSBool ok;
     JSObject *errProto, *errObject;
@@ -1119,17 +1120,20 @@ js_ErrorToException(JSContext *cx, const
      * Tell our caller to report immediately if this report is just a warning.
      */
     JS_ASSERT(reportp);
     if (JSREPORT_IS_WARNING(reportp->flags))
         return JS_FALSE;
 
     /* Find the exception index associated with this error. */
     errorNumber = (JSErrNum) reportp->errorNumber;
-    errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
+    if (!callback || callback == js_GetErrorMessage)
+        errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
+    else
+        errorString = callback(userRef, NULL, errorNumber);
     exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
     JS_ASSERT(exn < JSEXN_LIMIT);
 
 #if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
     /* Print the error name and the associated exception name to stderr */
     fprintf(stderr, "%s\t%s\n",
             errortoexnname[errorNumber].name,
             errortoexnname[errorNumber].exception);
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -58,17 +58,18 @@ js_InitExceptionClasses(JSContext *cx, J
  * Given a JSErrorReport, check to see if there is an exception associated with
  * the error number.  If there is, then create an appropriate exception object,
  * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
  * error report.  Exception-aware host error reporters should probably ignore
  * error reports so flagged.  Returns JS_TRUE if an associated exception is
  * found and set, JS_FALSE otherwise.
  */
 extern JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
+                    JSErrorCallback callback, void *userRef);
 
 /*
  * Called if a JS API call to js_Execute or js_InternalCall fails; calls the
  * error reporter with the error report associated with any uncaught exception
  * that has been raised.  Returns true if there was an exception pending, and
  * the error reporter was actually called.
  *
  * The JSErrorReport * that the error reporter is called with is currently
--- a/js/src/jsscan.cpp
+++ b/js/src/jsscan.cpp
@@ -602,17 +602,17 @@ ReportCompileErrorNumberVA(JSContext *cx
     onError = cx->errorReporter;
 
     /*
      * Try to raise an exception only if there isn't one already set --
      * otherwise the exception will describe the last compile-time error,
      * which is likely spurious.
      */
     if (!(ts->flags & TSF_ERROR)) {
-        if (js_ErrorToException(cx, message, &report))
+        if (js_ErrorToException(cx, message, &report, NULL, NULL))
             onError = NULL;
     }
 
     /*
      * Suppress any compile-time errors that don't occur at the top level.
      * This may still fail, as interplevel may be zero in contexts where we
      * don't really want to call the error reporter, as when js is called
      * by other code which could catch the error.