If dart2js-compiled code is run in strict mode (such as when it's loaded as an ECMAScript module as in the browser), and it tries to catch an exception from JavaScript that's just a string, it will crash with TypeError: Cannot create property '$cachedTrace' on string. This is because of the helper function getTraceFromException():
getTraceFromException(exception) {
var trace;
if (exception instanceof A.ExceptionAndStackTrace)
return exception.stackTrace;
if (exception == null)
return new A._StackTrace(exception);
trace = exception.$cachedTrace;
if (trace != null)
return trace;
return exception.$cachedTrace = new A._StackTrace(exception);
}
Specifically, exception.$cachedTrace = is not valid in strict mode if exception is a JS value type. Here's a simple reproduction (you can imagine that the exception might come from a JS callback instead of jsThrow()):
// test.dart
import 'package:js/js.dart';
@JS("Function")
class JSFunction {
external JSFunction(String arg1, [String? arg2, String? arg3]);
external Object? call([Object? arg1, Object? arg2, Object? arg3]);
}
/// Throws [error] like JS would, without any Dart wrappers.
Never jsThrow(Object error) => _jsThrow.call(error) as Never;
final _jsThrow = JSFunction("error", "throw error;");
void main(List<String> args) {
try {
jsThrow('oh no');
} catch (error, stackTrace) {
print('error: $error, trace: $stackTrace');
}
}
Compile this to JS, load it with import in a browser, and you'll see TypeError: Cannot create property '$cachedTrace' on string 'oh no'.
If dart2js-compiled code is run in strict mode (such as when it's loaded as an ECMAScript module as in the browser), and it tries to catch an exception from JavaScript that's just a string, it will crash with
TypeError: Cannot create property '$cachedTrace' on string. This is because of the helper functiongetTraceFromException():Specifically,
exception.$cachedTrace =is not valid in strict mode ifexceptionis a JS value type. Here's a simple reproduction (you can imagine that the exception might come from a JS callback instead ofjsThrow()):Compile this to JS, load it with
importin a browser, and you'll seeTypeError: Cannot create property '$cachedTrace' on string 'oh no'.