From f93feaf59205b349fe418363f545f3076265ee35 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 15 Jan 2021 15:36:36 -0800 Subject: [PATCH 1/2] Don't try to cast an error to JsError Dart's runtime understanding of what a "JsError" is isn't sufficient to make sense of everything that might be thrown by, for example, a custom function with an error. --- CHANGELOG.md | 7 +++++++ lib/src/node.dart | 4 ++-- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aff797675..8210ecec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.32.5 + +### JS API + +* Avoid possible mangled error messages when custom functions or importers throw + unexpected exceptions. + ## 1.32.4 * No user-visible changes. diff --git a/lib/src/node.dart b/lib/src/node.dart index b5c500dfc..ca7983c0e 100644 --- a/lib/src/node.dart +++ b/lib/src/node.dart @@ -65,13 +65,13 @@ void main() { /// /// [render]: https://github.com/sass/node-sass#options void _render( - RenderOptions options, void callback(JsError error, RenderResult result)) { + RenderOptions options, void callback(Object error, RenderResult result)) { if (options.fiber != null) { options.fiber.call(allowInterop(() { try { callback(null, _renderSync(options)); } catch (error) { - callback(error as JsError, null); + callback(error, null); } return null; })).run(); diff --git a/pubspec.yaml b/pubspec.yaml index e9d024f43..73782ea6c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.32.4 +version: 1.32.5 description: A Sass implementation in Dart. author: Sass Team homepage: https://github.com/sass/dart-sass From 072c5252cad0c8e18cdacc4c553f39158ba8658c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 15 Jan 2021 16:09:30 -0800 Subject: [PATCH 2/2] Wrap fiber.yield() calls in runZoned() This resets the current zone after the fiber returns, where otherwise it could end up set to a different zone entirely, since Dart's Zone API is unaware of fibers. Closes #1204 --- CHANGELOG.md | 3 +++ lib/src/node.dart | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8210ecec1..1aeb5bf90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### JS API +* Fix a few infrequent errors when calling `render()` with `fiber` multiple + times simultaneously. + * Avoid possible mangled error messages when custom functions or importers throw unexpected exceptions. diff --git a/lib/src/node.dart b/lib/src/node.dart index ca7983c0e..1711875a5 100644 --- a/lib/src/node.dart +++ b/lib/src/node.dart @@ -212,8 +212,12 @@ List _parseFunctions(RenderOptions options, }) ]; var result = Function.apply(callback as Function, jsArguments); - return unwrapValue( - isUndefined(result) ? options.fiber.yield() : result); + return unwrapValue(isUndefined(result) + // Run `fiber.yield()` in runZoned() so that Dart resets the current + // zone once it's done. Otherwise, interweaving fibers can leave + // `Zone.current` in an inconsistent state. + ? runZoned(() => options.fiber.yield()) + : result); })); } else if (!asynch) { result.add(BuiltInCallable.parsed( @@ -283,7 +287,11 @@ NodeImporter _parseImporter(RenderOptions options, DateTime start) { // [importer] calls `done()` synchronously. scheduleMicrotask(() => fiber.run(result)); })); - if (isUndefined(result)) return options.fiber.yield(); + + // Run `fiber.yield()` in runZoned() so that Dart resets the current + // zone once it's done. Otherwise, interweaving fibers can leave + // `Zone.current` in an inconsistent state. + if (isUndefined(result)) return runZoned(() => options.fiber.yield()); return result; }) as JSFunction; }).toList();