Skip to content

Commit 53aa546

Browse files
committed
fix: make compiler error extend from Error
We originally didn't extend from `Error` anymore because its fields are of no real value to us, and has problems with serialization in a worker context. Turns out this was a mistake, because various build tools rely on errors being thrown as something that extends Error, else they try to wrap it in their own error. We therefore revert that change while still trying to preserve most of the advantages of not extending `Error`, namely nuking the useless stack trace and making sure the message is enumerable.
1 parent f52a303 commit 53aa546

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

.changeset/wet-timers-shop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: make compiler error extend from `Error`

packages/svelte/scripts/process-messages/templates/compile-errors.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,34 @@ import { CompileDiagnostic } from './utils/compile_diagnostic.js';
22

33
/** @typedef {{ start?: number, end?: number }} NodeLike */
44

5-
class InternalCompileError extends CompileDiagnostic {
5+
class InternalCompileError extends Error {
66
name = 'CompileError';
7+
message = ''; // ensure this property is enumerable
8+
#diagnostic;
79

810
/**
911
* @param {string} code
1012
* @param {string} message
1113
* @param {[number, number] | undefined} position
1214
*/
1315
constructor(code, message, position) {
14-
super(code, message, position);
16+
super(message);
17+
this.message = message; // needs to be set explicitly because we did set it to an empty string above and the super call doesn't change that
18+
this.stack = ''; // avoid unnecessary noise; don't set it as a class property or it becomes enumerable
19+
20+
// We want to extend from Error so that various bundler plugins properly handle it.
21+
// But we also want to share the same object shape with that of warnings, therefore
22+
// we create an instance of the shared class an copy over its properties.
23+
this.#diagnostic = new CompileDiagnostic(code, message, position);
24+
Object.assign(this, this.#diagnostic);
25+
}
26+
27+
toString() {
28+
return this.#diagnostic.toString();
29+
}
30+
31+
toJSON() {
32+
return this.#diagnostic.toJSON();
1533
}
1634
}
1735

packages/svelte/src/compiler/errors.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,33 @@
33
import { CompileDiagnostic } from './utils/compile_diagnostic.js';
44

55
/** @typedef {{ start?: number, end?: number }} NodeLike */
6-
class InternalCompileError extends CompileDiagnostic {
6+
class InternalCompileError extends Error {
77
name = 'CompileError';
8+
message = ''; // ensure this property is enumerable
9+
#diagnostic;
810

911
/**
1012
* @param {string} code
1113
* @param {string} message
1214
* @param {[number, number] | undefined} position
1315
*/
1416
constructor(code, message, position) {
15-
super(code, message, position);
17+
super(message);
18+
this.message = message; // needs to be set explicitly because we did set it to an empty string above and the super call doesn't change that
19+
this.stack = ''; // avoid unnecessary noise; don't set it as a class property or it becomes enumerable
20+
// We want to extend from Error so that various bundler plugins properly handle it.
21+
// But we also want to share the same object shape with that of warnings, therefore
22+
// we create an instance of the shared class an copy over its properties.
23+
this.#diagnostic = new CompileDiagnostic(code, message, position);
24+
Object.assign(this, this.#diagnostic);
25+
}
26+
27+
toString() {
28+
return this.#diagnostic.toString();
29+
}
30+
31+
toJSON() {
32+
return this.#diagnostic.toJSON();
1633
}
1734
}
1835

packages/svelte/src/compiler/utils/compile_diagnostic.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ function get_code_frame(source, line, column) {
5151
/** @implements {ICompileDiagnostic} */
5252
export class CompileDiagnostic {
5353
name = 'CompileDiagnostic';
54-
// adding an empty stack so that vite will show the file and frame during build
55-
stack = '';
5654

5755
/**
5856
* @param {string} code

0 commit comments

Comments
 (0)