diff --git a/CHANGELOG.md b/CHANGELOG.md index 219e1f2a9..5d4459a65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ * Don't crash when a Windows path is returned by a custom Node importer at the same time as file contents. +* Don't crash when an error occurs in a stylesheet loaded via a custom importer + with a custom URL scheme. ## 1.37.5 diff --git a/lib/src/node.dart b/lib/src/node.dart index a97d5f93c..709b2a3fe 100644 --- a/lib/src/node.dart +++ b/lib/src/node.dart @@ -183,10 +183,20 @@ RenderResult _renderSync(RenderOptions options) { /// Converts an exception to a [JsError]. JsError _wrapException(Object exception) { if (exception is SassException) { + String file; + var url = exception.span.sourceUrl; + if (url == null) { + file = 'stdin'; + } else if (url.scheme == 'file') { + file = p.fromUri(url); + } else { + file = url.toString(); + } + return _newRenderError(exception.toString().replaceFirst("Error: ", ""), line: exception.span.start.line + 1, column: exception.span.start.column + 1, - file: exception.span.sourceUrl.andThen(p.fromUri) ?? 'stdin', + file: file, status: 1); } else { return JsError(exception.toString()); diff --git a/test/node_api/importer_test.dart b/test/node_api/importer_test.dart index 50f5787fd..f36142e7e 100644 --- a/test/node_api/importer_test.dart +++ b/test/node_api/importer_test.dart @@ -704,6 +704,24 @@ void main() { " ╵\n" " stdin 1:9 root stylesheet")); }); + + test("it occurs in a file with a custom URL scheme", () { + var error = + renderSyncError(RenderOptions( + data: "@import 'foo:bar'", + importer: allowInterop(expectAsync2((String _, void __) { + return NodeImporterResult(contents: '@error "oh no";'); + })))); + + expect(error, + toStringAndMessageEqual("\"oh no\"\n" + " ╷\n" + "1 │ @error \"oh no\";\n" + " │ ^^^^^^^^^^^^^^\n" + " ╵\n" + " foo:bar 1:1 @import\n" + " stdin 1:9 root stylesheet")); + }); }); group("render()", () {