{{ message }}
fix: surface real background task start errors and stop orphaned daemons#535
Merged
Conversation
Starting a background task forks a daemon that imports the task file. Three problems made failures opaque and unsafe (#484): - A failed import (missing file, a runtime that cannot run the file, or unsupported TypeScript syntax in Node's strip-only mode, e.g. enums) crashed the daemon and the parent only saw "Start operation timed out" or an opaque exit code; the real cause went to the child's stderr. - The start timeout was a hard-coded 5s. A task file that loads slowly (transpile, large graph) could not be accommodated. - On a failed/timed-out start the daemon was never killed, so a daemon that finished loading late kept running the schedule on its own, causing orphaned and duplicate executions. Fixes: - The daemon catches load/start failures and forwards the real error to the parent (daemon:error), which rejects start() with the actual cause. - New `startTimeout` option (ms, default 5000) plus an actionable timeout message. - Any failed start now kills the daemon and clears the fork (no orphans). - schedule() routes a background task's auto-start failure to the logger instead of leaving an unhandled rejection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Closes #484
Problem
Starting a background task forks a daemon that imports the task file. Three problems made failures opaque and unsafe, reproduced against the real build on Node 24:
enum/namespace/decorators) crashed the daemon. The parent only sawStart operation timed outornode-cron daemon exited with code 1; the actual cause (TypeScript enum is not supported in strip-only mode,Cannot find module ...) only reached the child's stderr. This matches @rudewalt (Node 24) and @merencia's loader hypothesis.Fix
daemon:error);start()rejects with the actual cause.startTimeoutoption (ms, default 5000) and an actionable timeout message.schedule()routes a background task's auto-start failure to the configured logger instead of leaving an unhandled rejection (the OP'sUnhandledRejection).Tests
Deterministic, written first (red), then made green:
start()with the real cause ondaemon:error;startTimeoutis honoured and the timeout message is actionable;schedule()logs a background start failure instead of throwing unhandled.End-to-end verified against the built
dist(enum.ts-> real error surfaced; slow load + shortstartTimeout-> daemon killed, no orphan executions).Honest scope note
node-cron cannot transpile TypeScript for you: on a strip-only runtime an
enumstill will not run. This change makes the failure diagnosable (you see the exact reason and how to fix it:--experimental-transform-types, tsx/ts-node, or a compiled.js) and stops the orphaned executions. It does not magically run unsupported syntax.