fix(async-retryer): preserve non-Error message and cause in normalized errors#223
fix(async-retryer): preserve non-Error message and cause in normalized errors#223theBGuy wants to merge 2 commits into
Conversation
📝 WalkthroughWalkthroughThis PR fixes error normalization in ChangesAsyncRetryer Error Normalization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR improves AsyncRetryer error normalization so that when a non-Error value (e.g., a plain object) is thrown, the normalized Error preserves a readable message and retains the original thrown value via cause.
Changes:
- Normalize non-
Errorthrown values by extracting amessagefield when present and attaching the original value asError.cause. - Add a regression test ensuring plain-object error
messageandcauseare preserved. - Add a changeset to publish the fix as a patch.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/pacer/src/async-retryer.ts | Updates error normalization to preserve plain-object messages and attach the original thrown value as cause. |
| packages/pacer/tests/async-retryer.test.ts | Adds a test covering thrown plain objects and verifying message/cause behavior. |
| .changeset/big-bikes-wash.md | Documents the patch release for the error-normalization fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| lastError = | ||
| error instanceof Error | ||
| ? error | ||
| : new Error( | ||
| typeof error === 'object' && | ||
| error !== null && | ||
| typeof (error as any).message === 'string' | ||
| ? (error as any).message | ||
| : String(error), | ||
| { cause: error }, | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/pacer/tests/async-retryer.test.ts (1)
391-407: 💤 Low valueConsider adding test coverage for additional edge cases.
The current test validates the main use case (plain object with string message), and existing tests cover string, null, and undefined. For completeness, you might consider adding tests for:
- Plain object without a
messageproperty (should fall back toString(error))- Plain object with non-string
messageproperty (e.g.,{ message: 123 })These would ensure the fallback logic is thoroughly validated.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/pacer/tests/async-retryer.test.ts` around lines 391 - 407, Add two new tests in packages/pacer/tests/async-retryer.test.ts next to the existing "should preserve plain object error message and cause" test to cover edge cases: (1) a plain object error without a message property (e.g., { code: 'E002' }) and assert that AsyncRetryer.execute() produces an Error whose message falls back to String(error) and whose cause is the original object; (2) a plain object with a non-string message (e.g., { message: 123 }) and assert that execute() converts that message to a string for Error.message and sets cause to the original object; reference the AsyncRetryer class and its execute() method when locating where to add these tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/pacer/tests/async-retryer.test.ts`:
- Around line 391-407: Add two new tests in
packages/pacer/tests/async-retryer.test.ts next to the existing "should preserve
plain object error message and cause" test to cover edge cases: (1) a plain
object error without a message property (e.g., { code: 'E002' }) and assert that
AsyncRetryer.execute() produces an Error whose message falls back to
String(error) and whose cause is the original object; (2) a plain object with a
non-string message (e.g., { message: 123 }) and assert that execute() converts
that message to a string for Error.message and sets cause to the original
object; reference the AsyncRetryer class and its execute() method when locating
where to add these tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 60b245f8-b810-48ce-aed3-227146820f8a
📒 Files selected for processing (3)
.changeset/big-bikes-wash.mdpackages/pacer/src/async-retryer.tspackages/pacer/tests/async-retryer.test.ts
🎯 Changes
✅ Checklist
🚀 Release Impact
Summary by CodeRabbit