run(): a failed polling pump leaves the process alive and silent (#1351) - #1360
Conversation
Michi-Task: r1ex Michi-Issue: 1351
Michi-Task: r2ex Michi-Issue: 1351
Michi-Task: r3dc Michi-Issue: 1351
|
😺 Michi — all tasks done, CI green, marked ready for review. Suggestion #1 (log the fatal poll-stop to stderr before rethrowing) landed earlier in #1358, so this PR covers the rest:
Note on the default: I chose CI: all GitHub Actions + AppVeyor green; E2E skipped by design. Full local gate ( Waiting for your merge. 🐾 |
…#1351) Michi-Task: r4rd Michi-Issue: 1351
There was a problem hiding this comment.
🟡 Changes recommended
Exit handling has ownership, teardown-error, and stderr-flush gaps, while the new Redis ownership path lacks direct coverage.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds managed failure exit behavior for polling and owned Redis client teardown.
Changes:
- Adds
RunOptions.exitOnErrorand updates polling examples. - Adds URL-owned Redis clients with teardown support.
- Updates tests and generated API documentation.
File summaries
| File | Description |
|---|---|
src/node/run.ts |
Adds optional process exit on polling failure. |
src/bun/redis-storage.ts |
Adds URL-created, owned Redis clients. |
test/unit/run.test.ts |
Tests polling exit behavior. |
test/unit/bun/redis-storage.test.ts |
Tests injected-client ownership. |
examples/01-polling-bot.ts |
Demonstrates exitOnError. |
examples/06-keyboards.ts |
Enables exitOnError. |
examples/09-middleware.ts |
Enables exitOnError. |
examples/12-conversation.ts |
Enables exitOnError. |
examples/16-sessions.ts |
Enables exitOnError. |
examples/17-callback-tracking.ts |
Enables exitOnError. |
doc/api.md |
Documents the updated public API. |
Review details
- Files reviewed: 11/11 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (owned) await bot.close(); | ||
| // Teardown is done; a supervisor can now restart a clean process. | ||
| if (failed && exitOnError) process.exit(1); |
| } finally { | ||
| if (owned) await bot.close(); | ||
| // Teardown is done; a supervisor can now restart a clean process. | ||
| if (failed && exitOnError) process.exit(1); |
| this.owned = options.client === undefined && options.url !== undefined; | ||
| this.client = options.client ?? (options.url !== undefined ? new RedisClient(options.url) : redis); |
…rr (#1351) Michi-Task: r5hx Michi-Issue: 1351
|
😺 Michi — applied the Codex + Copilot review; CI green.
New tests: teardown-throws-still-exits, lost-race-does-not-exit, and the full url-owned Redis lifecycle. CI: all GitHub Actions + AppVeyor green; E2E skipped by design. Full local gate ( Waiting for your merge. 🐾 |
|
😺 Michi — merged, all done 🐾 |
Closes #1351
Suggestion #1 (log the fatal poll-stop to stderr before rethrowing) already landed in #1358. This PR adds the remaining scope.
run(): add opt-inexitOnError(default false) - on a fatal poll-stop, after teardown + the stderr log, exit non-zero so a supervisor restarts the bot; newRunOptionstype; unit test (stubbedprocess.exit)await run(bot)to model failure handling (await run(bot, { exitOnError: true }))doc/api.mdfor the newRunOptions/runsignatureRedisSessionStorage: add aurloption so the store can own the client it opens andclose()it on teardown (mirrors the sql/sqliteownedpattern) - closes the one teardown gap found while verifyingbot.close()for run(): a failed polling pump leaves the process alive and silent #1351; unit test + docsexitOnError(Codex + Copilot): gate the hard exit on owning the pump (a losing double-run must not kill the healthy process), run it in a nestedfinallyso a throwing teardown can't skip it, and flush the stderr diagnostic before exiting; tests for teardown-throws and lost-raceprotected createClientseam - construct/close the owned client, idempotent close, and use-after-close rejects (Copilot)