Bug 739659 - Try duck typing in js_ReportUncaughtException. r=luke

This commit is contained in:
Masatoshi Kimura 2012-04-03 20:08:28 -04:00
parent 17a428d27a
commit 932c8abcc5
4 changed files with 81 additions and 36 deletions

View File

@ -16,7 +16,7 @@
<script type="text/javascript">
const workerCount = 3;
const errorMessage = "expectedError";
const errorMessage = "Error: expectedError";
const errorFilename = "http://mochi.test:8888/tests/dom/workers/test/" +
"errorPropagation_worker.js";
const errorLineno = 48;

View File

@ -20,7 +20,7 @@
}
worker.onerror = function(event) {
is(event.message, "foo!", "Got wrong error message!");
is(event.message, "Error: foo!", "Got wrong error message!");
event.preventDefault();
SimpleTest.finish();
}

View File

@ -14,8 +14,8 @@
const filename = "http://mochi.test:8888/tests/dom/workers/test/" +
"recursiveOnerror_worker.js";
const errors = [
{ message: "2", lineno: 6 },
{ message: "1", lineno: 10 }
{ message: "Error: 2", lineno: 6 },
{ message: "Error: 1", lineno: 10 }
]
var errorCount = 0;

View File

@ -1189,15 +1189,36 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
return true;
}
static bool
IsDuckTypedErrorObject(JSContext *cx, JSObject *exnObject, const char **filename_strp)
{
JSBool found;
if (!JS_HasProperty(cx, exnObject, js_message_str, &found) || !found)
return false;
const char *filename_str = *filename_strp;
if (!JS_HasProperty(cx, exnObject, filename_str, &found) || !found) {
/* DOMException duck quacks "filename" (all lowercase) */
filename_str = "filename";
if (!JS_HasProperty(cx, exnObject, filename_str, &found) || !found)
return false;
}
if (!JS_HasProperty(cx, exnObject, js_lineNumber_str, &found) || !found)
return false;
*filename_strp = filename_str;
return true;
}
JSBool
js_ReportUncaughtException(JSContext *cx)
{
jsval exn;
JSObject *exnObject;
jsval roots[5];
jsval roots[6];
JSErrorReport *reportp, report;
JSString *str;
const char *bytes;
if (!JS_IsExceptionPending(cx))
return true;
@ -1226,51 +1247,75 @@ js_ReportUncaughtException(JSContext *cx)
/* XXX L10N angels cry once again. see also everywhere else */
str = ToString(cx, exn);
JSAutoByteString bytesStorage;
if (!str) {
bytes = "unknown (can't convert to string)";
} else {
if (str)
roots[1] = StringValue(str);
if (!bytesStorage.encode(cx, str))
return false;
bytes = bytesStorage.ptr();
}
const char *filename_str = js_fileName_str;
JSAutoByteString filename;
if (!reportp && exnObject && exnObject->isError()) {
if (!JS_GetProperty(cx, exnObject, js_message_str, &roots[2]))
return false;
if (JSVAL_IS_STRING(roots[2])) {
bytesStorage.clear();
if (!bytesStorage.encode(cx, str))
return false;
bytes = bytesStorage.ptr();
if (!reportp && exnObject &&
(exnObject->isError() ||
IsDuckTypedErrorObject(cx, exnObject, &filename_str)))
{
JSString *name = NULL;
if (JS_GetProperty(cx, exnObject, js_name_str, &roots[2]) &&
JSVAL_IS_STRING(roots[2]))
{
name = JSVAL_TO_STRING(roots[2]);
}
if (!JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]))
return false;
str = ToString(cx, roots[3]);
if (!str || !filename.encode(cx, str))
return false;
JSString *msg = NULL;
if (JS_GetProperty(cx, exnObject, js_message_str, &roots[3]) &&
JSVAL_IS_STRING(roots[3]))
{
msg = JSVAL_TO_STRING(roots[3]);
}
if (name && msg) {
JSString *colon = JS_NewStringCopyZ(cx, ": ");
if (!colon)
return false;
JSString *nameColon = JS_ConcatStrings(cx, name, colon);
if (!nameColon)
return false;
str = JS_ConcatStrings(cx, nameColon, msg);
if (!str)
return false;
} else if (name) {
str = name;
} else if (msg) {
str = msg;
}
if (JS_GetProperty(cx, exnObject, filename_str, &roots[4])) {
JSString *tmp = ToString(cx, roots[4]);
if (tmp)
filename.encode(cx, tmp);
}
if (!JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4]))
return false;
uint32_t lineno;
if (!ToUint32(cx, roots[4], &lineno))
return false;
if (!JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[5]) ||
!ToUint32(cx, roots[5], &lineno))
{
lineno = 0;
}
reportp = &report;
PodZero(&report);
report.filename = filename.ptr();
report.lineno = (unsigned) lineno;
if (JSVAL_IS_STRING(roots[2])) {
JSFixedString *fixed = JSVAL_TO_STRING(roots[2])->ensureFixed(cx);
if (!fixed)
return false;
report.ucmessage = fixed->chars();
if (str) {
if (JSFixedString *fixed = str->ensureFixed(cx))
report.ucmessage = fixed->chars();
}
}
JSAutoByteString bytesStorage;
const char *bytes = NULL;
if (str)
bytes = bytesStorage.encode(cx, str);
if (!bytes)
bytes = "unknown (can't convert to string)";
if (!reportp) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_UNCAUGHT_EXCEPTION, bytes);