Skip to content

Commit 3f0c29a

Browse files
committed
Set error cause property
Since EcmaScript 2022, `Error` objects support a `cause` property, allowing for tracking the root cause of an error. This commit set this property where appropriate.
1 parent b97b79a commit 3f0c29a

File tree

7 files changed

+42
-42
lines changed

7 files changed

+42
-42
lines changed

src/font-loader.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@ describe('font-loader', () => {
142142
it('rejects if font could not be loaded', async () => {
143143
const store = new FontStore(fontLoader);
144144

145-
await expect(store.selectFont({ fontFamily: 'foo' })).rejects.toThrowError(
146-
"Could not load font for 'foo', style=normal, weight=normal: No such font defined",
145+
await expect(() => store.selectFont({ fontFamily: 'foo' })).rejects.toThrow(
146+
expect.objectContaining({
147+
message: "Could not load font for 'foo', style=normal, weight=normal",
148+
cause: new Error('No such font defined'),
149+
}),
147150
);
148151
});
149152

@@ -186,13 +189,12 @@ describe('font-loader', () => {
186189
it('caches errors from font loader', async () => {
187190
const store = new FontStore(fontLoader);
188191

189-
await expect(store.selectFont({ fontFamily: 'foo' })).rejects.toThrowError(
190-
"Could not load font for 'foo', style=normal, weight=normal: No such font defined",
192+
await expect(() => store.selectFont({ fontFamily: 'foo' })).rejects.toThrow(
193+
expect.objectContaining({
194+
message: "Could not load font for 'foo', style=normal, weight=normal",
195+
cause: new Error('No such font defined'),
196+
}),
191197
);
192-
await expect(store.selectFont({ fontFamily: 'foo' })).rejects.toThrowError(
193-
"Could not load font for 'foo', style=normal, weight=normal: No such font defined",
194-
);
195-
expect(fontLoader.loadFont).toHaveBeenCalledTimes(1);
196198
});
197199
});
198200
});

src/font-loader.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ export class FontStore {
111111
} catch (error) {
112112
const { fontFamily: family, fontStyle: style, fontWeight: weight } = selector;
113113
const selectorStr = `'${family}', style=${style ?? 'normal'}, weight=${weight ?? 'normal'}`;
114-
throw new Error(
115-
`Could not load font for ${selectorStr}: ${(error as Error)?.message ?? error}`,
116-
);
114+
throw new Error(`Could not load font for ${selectorStr}`, { cause: error });
117115
}
118116
const fkFont = fontkit.create(loadedFont.data);
119117
return pickDefined({

src/image-loader.test.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ describe('image-loader', () => {
2121
it('rejects if image cannot be loaded', async () => {
2222
const loader = new ImageLoader([]);
2323

24-
await expect(loader.loadImage({ name: 'foo' })).rejects.toThrowError(
25-
"Could not load image 'foo': ENOENT: no such file or directory, open 'foo'",
24+
await expect(() => loader.loadImage({ name: 'foo' })).rejects.toThrow(
25+
expect.objectContaining({
26+
message: "Could not load image 'foo'",
27+
cause: new Error("ENOENT: no such file or directory, open 'foo'"),
28+
}),
2629
);
2730
});
2831

@@ -64,8 +67,11 @@ describe('image-loader', () => {
6467
it('rejects if image could not be loaded', async () => {
6568
const store = new ImageStore(imageLoader);
6669

67-
await expect(store.selectImage({ name: 'foo' })).rejects.toThrowError(
68-
"Could not load image 'foo': No such image",
70+
await expect(() => store.selectImage({ name: 'foo' })).rejects.toThrow(
71+
expect.objectContaining({
72+
message: "Could not load image 'foo'",
73+
cause: new Error('No such image'),
74+
}),
6975
);
7076
});
7177

@@ -120,13 +126,12 @@ describe('image-loader', () => {
120126
it('caches errors from image loader', async () => {
121127
const store = new ImageStore(imageLoader);
122128

123-
await expect(store.selectImage({ name: 'foo' })).rejects.toThrowError(
124-
"Could not load image 'foo': No such image",
129+
await expect(() => store.selectImage({ name: 'foo' })).rejects.toThrow(
130+
expect.objectContaining({
131+
message: "Could not load image 'foo'",
132+
cause: new Error('No such image'),
133+
}),
125134
);
126-
await expect(store.selectImage({ name: 'foo' })).rejects.toThrowError(
127-
"Could not load image 'foo': No such image",
128-
);
129-
expect(imageLoader.loadImage).toHaveBeenCalledTimes(1);
130135
});
131136
});
132137
});

src/image-loader.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ export class ImageLoader {
2828
data = await readFile(selector.name);
2929
return { data };
3030
} catch (error) {
31-
throw new Error(
32-
`Could not load image '${selector.name}': ${(error as Error)?.message ?? error}`,
33-
);
31+
throw new Error(`Could not load image '${selector.name}'`, { cause: error });
3432
}
3533
}
3634
}
@@ -53,9 +51,7 @@ export class ImageStore {
5351
try {
5452
loadedImage = await this.#imageLoader.loadImage(selector);
5553
} catch (error) {
56-
throw new Error(
57-
`Could not load image '${selector.name}': ${(error as Error)?.message ?? error}`,
58-
);
54+
throw new Error(`Could not load image '${selector.name}'`, { cause: error });
5955
}
6056
const { data } = loadedImage;
6157
const format = determineImageFormat(data);

src/images.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ export function registerImage(image: Image, pdfDoc: PDFDocument) {
5050
: JpegEmbedder.for(image.data));
5151
embedder.embedIntoContext(pdfDoc.context, ref);
5252
} catch (error) {
53-
throw new Error(
54-
`Could not embed image "${image.name}": ${(error as Error)?.message ?? error}`,
55-
);
53+
throw new Error(`Could not embed image "${image.name}"`, { cause: error });
5654
}
5755
},
5856
});

src/types.test.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,11 @@ describe('types', () => {
190190
});
191191

192192
it('throws when function returns invalid value', () => {
193-
const resolve = validate(() => 23);
194-
195-
expect(() => resolve()).toThrowError(
196-
'Supplied function for "test" returned invalid value: Expected string, got: 23',
193+
expect(validate(() => 23)).toThrow(
194+
expect.objectContaining({
195+
message: 'Supplied function for "test" returned invalid value',
196+
cause: new Error('Expected string, got: 23'),
197+
}),
197198
);
198199
});
199200

@@ -202,8 +203,11 @@ describe('types', () => {
202203
throw new Error('test error');
203204
});
204205

205-
expect(() => resolve()).toThrowError(
206-
'Supplied function for "test" threw: Error: test error',
206+
expect(resolve).toThrow(
207+
expect.objectContaining({
208+
message: 'Supplied function for "test" threw error',
209+
cause: new Error('test error'),
210+
}),
207211
);
208212
});
209213
});

src/types.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ export function dynamic<T = unknown>(
100100
try {
101101
return asType(result, type);
102102
} catch (error) {
103-
const errorStr = error instanceof Error ? (error.message ?? String(error)) : String(error);
104-
throw new Error(`${subject} returned invalid value: ${errorStr}`);
103+
throw new Error(`${subject} returned invalid value`, { cause: error });
105104
}
106105
};
107106
};
@@ -110,10 +109,8 @@ export function dynamic<T = unknown>(
110109
function safeCall(fn: (...params: unknown[]) => unknown, args: unknown[], subject: string) {
111110
try {
112111
return fn(...args);
113-
} catch (error: unknown) {
114-
const errorStr =
115-
error instanceof Error ? (error.stack ?? error.message ?? String(error)) : String(error);
116-
throw new Error(`${subject} threw: ${errorStr}`);
112+
} catch (error) {
113+
throw new Error(`${subject} threw error`, { cause: error });
117114
}
118115
}
119116

0 commit comments

Comments
 (0)