fix: Fix task runner error propagation (no-changelog) (#11291)

This commit is contained in:
Tomi Turtiainen 2024-10-17 13:17:33 +02:00 committed by GitHub
parent d2266c93a7
commit d330b6b94a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 28 deletions

View file

@ -758,17 +758,20 @@ describe('JsTaskRunner', () => {
await runner.receivedSettings(taskId, task.settings);
expect(sendSpy).toHaveBeenCalledWith(
JSON.stringify({
type: 'runner:taskerror',
taskId,
error: {
message: 'unknown is not defined [line 1]',
description: 'ReferenceError',
lineNumber: 1,
},
}),
);
}, 1000);
expect(sendSpy).toHaveBeenCalled();
const calledWith = sendSpy.mock.calls[0][0] as string;
expect(typeof calledWith).toBe('string');
const calledObject = JSON.parse(calledWith);
expect(calledObject).toEqual({
type: 'runner:taskerror',
taskId,
error: {
stack: expect.any(String),
message: 'unknown is not defined [line 1]',
description: 'ReferenceError',
lineNumber: 1,
},
});
});
});
});

View file

@ -42,6 +42,7 @@ describe('ExecutionError', () => {
expect(JSON.stringify(executionError)).toBe(
JSON.stringify({
stack: defaultStack,
message: 'a.unknown is not a function [line 2, for item 1]',
description: 'TypeError',
itemIndex: 1,

View file

@ -1,3 +1,24 @@
/**
* Makes the given error's `message` and `stack` properties enumerable
* so they can be serialized with JSON.stringify
*/
export function makeSerializable(error: Error) {
Object.defineProperties(error, {
message: {
value: error.message,
enumerable: true,
configurable: true,
},
stack: {
value: error.stack,
enumerable: true,
configurable: true,
},
});
return error;
}
/**
* Error that has its message property serialized as well. Used to transport
* errors over the wire.
@ -6,16 +27,6 @@ export abstract class SerializableError extends Error {
constructor(message: string) {
super(message);
// So it is serialized as well
this.makeMessageEnumerable();
}
private makeMessageEnumerable() {
Object.defineProperty(this, 'message', {
value: this.message,
enumerable: true, // This makes the message property enumerable
writable: true,
configurable: true,
});
makeSerializable(this);
}
}

View file

@ -27,6 +27,7 @@ import { type Task, TaskRunner } from '@/task-runner';
import { isErrorLike } from './errors/error-like';
import { ExecutionError } from './errors/execution-error';
import { makeSerializable } from './errors/serializable-error';
import type { RequireResolver } from './require-resolver';
import { createRequireResolver } from './require-resolver';
import { validateRunForAllItemsOutput, validateRunForEachItemOutput } from './result-validation';
@ -323,7 +324,7 @@ export class JsTaskRunner extends TaskRunner {
private toExecutionErrorIfNeeded(error: unknown): Error {
if (error instanceof Error) {
return error;
return makeSerializable(error);
}
if (isErrorLike(error)) {

View file

@ -21,10 +21,6 @@ export class WrappedExecutionError extends ApplicationError {
private copyErrorProperties(error: WrappableError) {
for (const key of Object.getOwnPropertyNames(error)) {
if (key === 'message' || key === 'stack') {
continue;
}
this[key] = error[key];
}
}