Skip to content

Commit 010161a

Browse files
fix(node-runtime-worker-thread): remove function properties before serializing errors COMPASS-5919 (#1762)
1 parent cf6d30c commit 010161a

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

packages/node-runtime-worker-thread/src/index.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,50 @@ describe('WorkerRuntime', function () {
144144
.to.have.property('stack')
145145
.matches(/SyntaxError: Syntax!/);
146146
});
147+
148+
it('COMPASS-5919 - correctly serializes babel parse errors', async function () {
149+
/**
150+
* babel syntax errors have a `clone()` method, which breaks structured cloning
151+
*/
152+
runtime = new WorkerRuntime('mongodb://nodb/', dummyOptions, {
153+
nodb: true,
154+
});
155+
156+
const err: Error = await runtime.evaluate('1 +* 3').catch((e) => e);
157+
158+
expect(err).to.be.instanceof(Error);
159+
expect(err).to.have.property('name', 'SyntaxError');
160+
});
161+
162+
context(
163+
'when `evaluate` returns an error that has a function property',
164+
function () {
165+
it('removes the function property from the error', async function () {
166+
runtime = new WorkerRuntime('mongodb://nodb/', dummyOptions, {
167+
nodb: true,
168+
});
169+
170+
const script = `
171+
class CustomError extends Error {
172+
constructor() {
173+
super('custom error');
174+
}
175+
foo() {
176+
return 'hello, world';
177+
}
178+
}
179+
throw new CustomError();
180+
`;
181+
182+
const err: Error = await runtime.evaluate(script).catch((e) => e);
183+
184+
expect(err).to.be.instanceof(Error);
185+
expect(err).to.have.property('name', 'Error');
186+
expect(err).not.to.have.property('foo');
187+
expect(err).to.have.property('message', 'custom error');
188+
});
189+
}
190+
);
147191
});
148192
});
149193

packages/node-runtime-worker-thread/src/serializer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ function getNames<T>(obj: T): (keyof T)[] {
2727
*/
2828
export function serializeError(err: Error) {
2929
// Name is the only constructor property we care about
30-
const keys = getNames(err).concat('name');
30+
const keys = getNames(err)
31+
.concat('name')
32+
// structured cloning cannot handle functions
33+
.filter((key) => typeof err[key] !== 'function');
3134
return keys.reduce((acc, key) => {
3235
(acc as any)[key] = err[key];
3336
return acc;

0 commit comments

Comments
 (0)