const { asyncResource, reject, resolve, workerNodeKey } = promiseResponse
const workerNode = this.workerNodes[workerNodeKey]
if (workerError != null) {
+ let error: Error
+ if (workerError.error != null) {
+ error = workerError.error
+ } else {
+ const err = new Error(workerError.message)
+ err.stack = workerError.stack
+ error = err
+ }
this.emitter?.emit(PoolEvents.taskError, workerError)
asyncResource != null
- ? asyncResource.runInAsyncScope(
- reject,
- this.emitter,
- workerError.message
- )
- : reject(workerError.message)
+ ? asyncResource.runInAsyncScope(reject, this.emitter, error)
+ : reject(error)
} else {
asyncResource != null
? asyncResource.runInAsyncScope(resolve, this.emitter, data)
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Task function operation '${message.taskFunctionOperation?.toString()}' failed on worker ${message.workerId?.toString()} with error: '${
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ message.workerError?.error?.message ??
message.workerError?.message
}'`
)
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
}' failed on worker ${errorResponse?.workerId?.toString()} with error: '${
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ errorResponse?.workerError?.error?.message ??
errorResponse?.workerError?.message
}'`
)
* Data triggering the error.
*/
readonly data?: Data
+ /**
+ * Error object.
+ */
+ readonly error?: Error
/**
* Error message.
*/
- readonly message: string
+ readonly message?: string
/**
* Task function name triggering the error.
*/
taskId,
workerError: {
data,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- message: `Task function '${name!}' not found`,
name,
+ ...this.handleError(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ new Error(`Task function '${name!}' not found`)
+ ),
},
})
return
taskId,
workerError: {
data,
- message: this.handleErrorMessage(error as Error | string),
name,
- stack: (error as Error).stack,
+ ...this.handleError(error as Error),
},
})
})
taskId,
workerError: {
data,
- message: this.handleErrorMessage(error as Error | string),
name,
- stack: (error as Error).stack,
+ ...this.handleError(error as Error),
},
})
} finally {
}
/**
- * Handles an error and convert it if needed to its message string.
- * Error are not structured-cloneable and cannot be sent to the main worker.
+ * Handles a worker error .
* @param error - The error raised by the worker.
- * @returns The error message.
+ * @returns The worker error object.
*/
- protected handleErrorMessage (error: Error | string): string {
- return error instanceof Error ? error.message : error
+ protected abstract handleError (error: Error): {
+ error?: Error
+ message?: string
+ stack?: string
}
/**
...(!status &&
error != null && {
workerError: {
- message: this.handleErrorMessage(error as Error | string),
name: taskFunctionProperties.name,
- stack: error.stack,
+ ...this.handleError(error),
},
}),
})
super(cluster.isPrimary, cluster.worker, taskFunctions, opts)
}
+ /**
+ * @inheritDoc
+ */
+ protected handleError (error: Error): { message: string; stack?: string } {
+ return { message: error.message, stack: error.stack }
+ }
+
/** @inheritDoc */
protected handleReadyMessage (message: MessageValue<Data>): void {
if (message.workerId === this.id && message.ready === false) {
/**
* @inheritDoc
*/
- protected override handleErrorMessage (error: Error | string): string {
- return error as string
+ protected handleError (error: Error): { error: Error } {
+ return { error }
}
/** @inheritDoc */
await expect(pool.execute(undefined, undefined, {})).rejects.toThrow(
new TypeError('transferList argument must be an array')
)
- await expect(pool.execute(undefined, 'unknown')).rejects.toBe(
- "Task function 'unknown' not found"
+ await expect(pool.execute(undefined, 'unknown')).rejects.toThrow(
+ new Error("Task function 'unknown' not found")
)
await pool.destroy()
await expect(pool.execute()).rejects.toThrow(
const workerId = dynamicThreadPool.workerNodes[0].info.id
await expect(dynamicThreadPool.setDefaultTaskFunction(0)).rejects.toThrow(
new Error(
- `Task function operation 'default' failed on worker ${workerId} with error: 'TypeError: name parameter is not a string'`
+ `Task function operation 'default' failed on worker ${workerId} with error: 'name parameter is not a string'`
)
)
await expect(
dynamicThreadPool.setDefaultTaskFunction(DEFAULT_TASK_NAME)
).rejects.toThrow(
new Error(
- `Task function operation 'default' failed on worker ${workerId} with error: 'Error: Cannot set the default task function reserved name as the default task function'`
+ `Task function operation 'default' failed on worker ${workerId} with error: 'Cannot set the default task function reserved name as the default task function'`
)
)
await expect(
dynamicThreadPool.setDefaultTaskFunction('unknown')
).rejects.toThrow(
new Error(
- `Task function operation 'default' failed on worker ${workerId} with error: 'Error: Cannot set the default task function to a non-existing task function'`
+ `Task function operation 'default' failed on worker ${workerId} with error: 'Cannot set the default task function to a non-existing task function'`
)
)
expect(dynamicThreadPool.listTaskFunctionsProperties()).toStrictEqual([
await expect(pool.mapExecute([undefined], undefined, {})).rejects.toThrow(
new TypeError('transferList argument must be an array')
)
- await expect(pool.mapExecute([undefined], 'unknown')).rejects.toBe(
- "Task function 'unknown' not found"
+ await expect(pool.mapExecute([undefined], 'unknown')).rejects.toThrow(
+ new Error("Task function 'unknown' not found")
)
let results = await pool.mapExecute(
[{}, {}, {}, {}],
} catch (e) {
inError = e
}
- expect(inError).toStrictEqual('Error Message from ClusterWorker')
+ expect(inError).toBeInstanceOf(Error)
+ expect(inError.message).toStrictEqual('Error Message from ClusterWorker')
+ expect(typeof inError.stack === 'string').toBe(true)
expect(taskError).toStrictEqual({
data,
message: 'Error Message from ClusterWorker',
} catch (e) {
inError = e
}
- expect(inError).toStrictEqual('Error Message from ClusterWorker:async')
+ expect(inError).toBeInstanceOf(Error)
+ expect(inError.message).toStrictEqual(
+ 'Error Message from ClusterWorker:async'
+ )
+ expect(typeof inError.stack === 'string').toBe(true)
expect(taskError).toStrictEqual({
data,
message: 'Error Message from ClusterWorker:async',
expect(inError.message).toStrictEqual('Error Message from ThreadWorker')
expect(taskError).toStrictEqual({
data,
- message: new Error('Error Message from ThreadWorker'),
+ error: new Error('Error Message from ThreadWorker'),
name: DEFAULT_TASK_NAME,
- stack: expect.any(String),
})
expect(
errorPool.workerNodes.some(
)
expect(taskError).toStrictEqual({
data,
- message: new Error('Error Message from ThreadWorker:async'),
+ error: new Error('Error Message from ThreadWorker:async'),
name: DEFAULT_TASK_NAME,
- stack: expect.any(String),
})
expect(
asyncErrorPool.workerNodes.some(
expect(worker.getMainWorker().send.calledOnce).toBe(true)
})
- it('Verify that handleErrorMessage() method is working properly', () => {
+ it('Verify that handleError() method is working properly', () => {
const error = new Error('Error as an error')
const worker = new ClusterWorker(() => {})
- expect(worker.handleErrorMessage(error)).toStrictEqual(error.message)
- const errorMessage = 'Error as a string'
- expect(worker.handleErrorMessage(errorMessage)).toStrictEqual(errorMessage)
+ expect(worker.handleError(error)).toStrictEqual({
+ message: error.message,
+ stack: error.stack,
+ })
})
it('Verify that sendToMainWorker() method invokes the getMainWorker() and send() methods', () => {
expect(worker.port.postMessage.calledOnce).toBe(true)
})
- it('Verify that handleErrorMessage() method is working properly', () => {
+ it('Verify that handleError() method is working properly', () => {
const error = new Error('Error as an error')
const worker = new ThreadWorker(() => {})
- expect(worker.handleErrorMessage(error)).toStrictEqual(error)
- const errorMessage = 'Error as a string'
- expect(worker.handleErrorMessage(errorMessage)).toStrictEqual(errorMessage)
+ expect(worker.handleError(error)).toStrictEqual({ error })
})
it('Verify that sendToMainWorker() method invokes the port property postMessage() method', () => {