Index: frog/frogsh |
diff --git a/frog/frogsh b/frog/frogsh |
index eb651dd7166be6fadf795c6e691c42ebf1f7fe42..721dd3b9c9c7929b67a286a863ed607905f22d25 100755 |
--- a/frog/frogsh |
+++ b/frog/frogsh |
@@ -73,42 +73,58 @@ Function.prototype.$genStub = function(argsLength, names) { |
// Translate a JavaScript exception to a Dart exception |
// TODO(jmesserly): cross browser support. This is Chrome specific. |
function $toDartException(e) { |
- var res = e; |
+ function attachStack(dartEx) { |
+ // TODO(jmesserly): setting the stack property is not a long term solution. |
+ var stack = e.stack; |
+ // The stack contains the error message, and the stack is all that is |
+ // printed (the exception's toString() is never called). Attempt to replace |
+ // the JS message (e.g. TypeError) with the Dart exception's toString(). |
+ if (typeof stack == 'string') { |
+ try { // toString is in a try-catch due to Issue 470. |
+ var message = dartEx.toString(); |
+ if (/^(Type|Range)Error:/.test(stack)) { |
+ // Remove JS message. |
+ stack = stack.substring(stack.indexOf('\n') + 1); |
+ } |
+ stack = message + '\n' + stack; |
+ } catch(_) { |
+ stack = '' + dartEx.constructor.name + ': (corrupt)\n' + stack; |
+ } |
+ } |
+ dartEx.stack = stack; |
+ return dartEx; |
+ } |
+ |
if (e instanceof TypeError) { |
switch(e.type) { |
case 'property_not_function': |
case 'called_non_callable': |
if (e.arguments[0] == null) { |
- res = new NullPointerException(); |
+ return attachStack(new NullPointerException()); |
} else { |
- res = new ObjectNotClosureException(); |
+ return attachStack(new ObjectNotClosureException()); |
} |
break; |
case 'non_object_property_call': |
case 'non_object_property_load': |
- res = new NullPointerException(); |
+ return attachStack(new NullPointerException()); |
break; |
case 'undefined_method': |
if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') { |
- res = new ObjectNotClosureException(); |
+ return attachStack(new ObjectNotClosureException()); |
} else { |
// TODO(jmesserly): can this ever happen? |
- res = new NoSuchMethodException('', e.arguments[0], []); |
+ // sra: Yes. |
+ return attachStack(new NoSuchMethodException('', e.arguments[0], [])); |
} |
break; |
} |
} else if (e instanceof RangeError) { |
if (e.message.indexOf('call stack') >= 0) { |
- res = new StackOverflowException(); |
+ return attachStack(new StackOverflowException()); |
} |
} |
- if (res) { |
- // TODO(jmesserly): setting the stack property is not a long term solution. |
- // Also it causes the exception to print as if it were a JS TypeError or |
- // RangeError, instead of using the proper toString. |
- res.stack = e.stack; |
- } |
- return res; |
+ return e; |
} |
function $notnull_bool(test) { |
return (test === true || test === false) ? test : test.is$bool(); // TypeError |
@@ -12154,7 +12170,7 @@ CoreJs.prototype.generate = function(w) { |
w.writeln("function $stackTraceOf(e) {\n // TODO(jmesserly): we shouldn't be relying on the e.stack property.\n // Need to mangle it.\n return (e && e.stack) ? e.stack : null;\n}"); |
} |
if ($notnull_bool(this.useToDartException)) { |
- w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartException(e) {\n var res = e;\n if (e instanceof TypeError) {\n switch(e.type) {\n case 'property_not_function':\n case 'called_non_callable':\n if (e.arguments[0] == null) {\n res = new NullPointerException();\n } else {\n res = new ObjectNotClosureException();\n }\n break;\n case 'non_object_property_call':\n case 'non_object_property_load':\n res = new NullPointerException();\n break;\n case 'undefined_method':\n if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') {\n res = new ObjectNotClosureException();\n } else {\n // TODO(jmesserly): can this ever happen?\n res = new NoSuchMethodException('', e.arguments[0], []);\n }\n break;\n }\n } else if (e instanceof RangeError) {\n if (e.message.indexOf('call stack') >= 0) {\n res = new StackOverflowException();\n }\n }\n if (res) {\n // TODO(jmesserly): setting the stack property is not a long term solution.\n // Also it causes the exception to print as if it were a JS TypeError or\n // RangeError, instead of using the proper toString.\n res.stack = e.stack;\n }\n return res;\n}"); |
+ w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartException(e) {\n function attachStack(dartEx) {\n // TODO(jmesserly): setting the stack property is not a long term solution.\n var stack = e.stack;\n // The stack contains the error message, and the stack is all that is\n // printed (the exception's toString() is never called). Attempt to replace\n // the JS message (e.g. TypeError) with the Dart exception's toString().\n if (typeof stack == 'string') {\n try { // toString is in a try-catch due to Issue 470.\n var message = dartEx.toString();\n if (/^(Type|Range)Error:/.test(stack)) {\n // Remove JS message.\n stack = stack.substring(stack.indexOf('\\n') + 1);\n }\n stack = message + '\\n' + stack;\n } catch(_) {\n stack = '' + dartEx.constructor.name + ': (corrupt)\\n' + stack;\n }\n }\n dartEx.stack = stack;\n return dartEx;\n }\n\n if (e instanceof TypeError) {\n switch(e.type) {\n case 'property_not_function':\n case 'called_non_callable':\n if (e.arguments[0] == null) {\n return attachStack(new NullPointerException());\n } else {\n return attachStack(new ObjectNotClosureException());\n }\n break;\n case 'non_object_property_call':\n case 'non_object_property_load':\n return attachStack(new NullPointerException());\n break;\n case 'undefined_method':\n if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') {\n return attachStack(new ObjectNotClosureException());\n } else {\n // TODO(jmesserly): can this ever happen?\n // sra: Yes.\n return attachStack(new NoSuchMethodException('', e.arguments[0], []));\n }\n break;\n }\n } else if (e instanceof RangeError) {\n if (e.message.indexOf('call stack') >= 0) {\n return attachStack(new StackOverflowException());\n }\n }\n return e;\n}"); |
} |
if ($notnull_bool(this.useNotNullBool)) { |
this.useThrow = true; |