diff --git a/src/hold-my-task.mjs b/src/hold-my-task.mjs index a1dd455..c335c26 100644 --- a/src/hold-my-task.mjs +++ b/src/hold-my-task.mjs @@ -1899,20 +1899,37 @@ export class HoldMyTask extends EventEmitter { error.taskId = item.id; if (item.callback) { - // Callback API - emit error event + // Callback API - deliver the failure to the callback try { item.callback(error, null); } catch (err) { this.emit("error", { error: err, task: item }); } - // Emit error event for callback API - this.emit("error", { error, task: item }); + // Also report it as a queue "error" event, but only to listeners: the callback already + // has the failure, so an unhandled-"error" throw would only crash the caller's process. + this._emitTaskError({ error, task: item }); } else if (item.reject) { // Promise API - just reject, don't emit error event (handled by promise) item.reject(error); } } + /** + * Emits a task failure as an `error` event when, and only when, a listener is attached. + * Used for callback-API task failures, which are always delivered to the task's callback + * as well; with no listener, EventEmitter would otherwise throw the event and crash the + * process before (or after) the callback could handle it. + * @param {Object} payload - Event payload + * @returns {void} + * @private + * @internal + */ + _emitTaskError(payload) { + if (this.listenerCount("error") > 0) { + this.emit("error", payload); + } + } + /** * Starts execution of a ready task. * @param {Object} item - The task item to execute @@ -1998,9 +2015,10 @@ export class HoldMyTask extends EventEmitter { : "error"; item.finishedAt = this.now(); - // Emit error event only for callback API (promise API conveys error via rejection) + // Emit error event only for callback API (promise API conveys error via rejection), + // and only to listeners - the callback below always receives the failure. if (item.callback) { - this.emit("error", item); + this._emitTaskError(item); } // Store final values on promise handle before rejecting (for promise API) diff --git a/tests/CallbackErrorWithoutListener.test.vitest.mjs b/tests/CallbackErrorWithoutListener.test.vitest.mjs new file mode 100644 index 0000000..3db9dba --- /dev/null +++ b/tests/CallbackErrorWithoutListener.test.vitest.mjs @@ -0,0 +1,103 @@ +/** + * + * @Project: @cldmv/holdmytask + * @Filename: /tests/CallbackErrorWithoutListener.test.vitest.mjs + * @Date: 2026-10-03T17:20:10-07:00 (1791073210) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-10-03T17:23:55-07:00 (1791073435) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + * + */ + +import { test, expect, describe } from "vitest"; +import { HoldMyTask } from "../src/hold-my-task.mjs"; + +// #53: a callback-style task failure must reach the callback even when nothing listens +// for the queue's `error` event; the event is only emitted when a listener exists. +const runCallbackTask = (q, task, options = {}) => + new Promise((resolve) => { + q.enqueue(task, (err, result) => resolve({ err, result }), options); + }); + +describe.each([ + { smartScheduling: true, mode: "Smart Scheduling" }, + { smartScheduling: false, mode: "Traditional Polling" } +])("callback task failures without an error listener ($mode)", ({ smartScheduling }) => { + test("a failing task delivers { type: 'error', error } to the callback without throwing", async () => { + const q = new HoldMyTask({ smartScheduling }); + const boom = new Error("boom"); + expect(q.listenerCount("error")).toBe(0); + const { err, result } = await runCallbackTask(q, () => { + throw boom; + }); + expect(err).toEqual({ type: "error", error: boom }); + expect(result).toBeNull(); + q.destroy(); + }); + + test("a timed-out task delivers { type: 'timeout', message } to the callback without throwing", async () => { + const q = new HoldMyTask({ smartScheduling }); + const { err, result } = await runCallbackTask(q, () => new Promise((resolve) => setTimeout(resolve, 500)), { timeout: 20 }); + expect(err).toEqual({ type: "timeout", message: "Task timed out after 20ms" }); + expect(result).toBeNull(); + q.destroy(); + }); + + test("an aborted task delivers { type: 'canceled', message: 'Task was aborted' } to the callback without throwing", async () => { + const q = new HoldMyTask({ smartScheduling }); + const { err, result } = await runCallbackTask(q, () => { + const abort = new Error("The operation was aborted"); + abort.name = "AbortError"; + throw abort; + }); + expect(err).toEqual({ type: "canceled", message: "Task was aborted" }); + expect(result).toBeNull(); + q.destroy(); + }); + + test("an expired task delivers its expire error to the callback without throwing", async () => { + const q = new HoldMyTask({ smartScheduling, concurrency: 1 }); + q.enqueue( + () => new Promise((resolve) => setTimeout(resolve, 60)), + () => {} + ); + const { err, result } = await runCallbackTask(q, () => "never", { expire: 10 }); + expect(err).toBeInstanceOf(Error); + expect(err.type).toBe("expire"); + expect(result).toBeNull(); + q.destroy(); + }); + + test("with an error listener attached, the event is still emitted and the callback still runs", async () => { + const q = new HoldMyTask({ smartScheduling }); + const events = []; + q.on("error", (payload) => events.push(payload)); + const boom = new Error("boom"); + const { err } = await runCallbackTask(q, () => { + throw boom; + }); + expect(err).toEqual({ type: "error", error: boom }); + expect(events).toHaveLength(1); + expect(events[0].error).toBe(boom); + expect(events[0].status).toBe("error"); + q.destroy(); + }); + + test("with an error listener attached, an expired callback task is still reported", async () => { + const q = new HoldMyTask({ smartScheduling, concurrency: 1 }); + const events = []; + q.on("error", (payload) => events.push(payload)); + q.enqueue( + () => new Promise((resolve) => setTimeout(resolve, 60)), + () => {} + ); + const { err } = await runCallbackTask(q, () => "never", { expire: 10 }); + expect(err.type).toBe("expire"); + expect(events.some((e) => e.error === err)).toBe(true); + q.destroy(); + }); +}); diff --git a/types/src/hold-my-task.d.mts.map b/types/src/hold-my-task.d.mts.map index 4611d0a..86dfc37 100644 --- a/types/src/hold-my-task.d.mts.map +++ b/types/src/hold-my-task.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"hold-my-task.d.mts","sourceRoot":"","sources":["../../src/hold-my-task.mjs"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"hold-my-task.d.mts","sourceRoot":"","sources":["../../src/hold-my-task.mjs"],"names":[],"mappings":"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"} \ No newline at end of file