fix(table): preserve error codes from db layer in Find methods#119
fix(table): preserve error codes from db layer in Find methods#119dev-arya23 wants to merge 2 commits into
Conversation
Table.Find, FindMany, FindManyWithOpts and the equivalent CachedTable methods unconditionally wrapped every error from the db layer as NotFound, destroying the error code that interpretMongoError had already set correctly. This caused callers using coreerrors.IsNotFound(err) to treat transient storage failures (connection resets, timeouts, auth failures) as genuine "document does not exist" results, leading to silent data loss in reconciliation paths. Fix: if the error from the db layer already carries a recognized error code (set by interpretMongoError), pass it through unchanged. Only wrap unrecognized errors as Internal. Add Internal error code (6) and IsInternal helper to the errors package. Fixes agentic-core/core#48
|
Warning Review limit reached
More reviews will be available in 51 minutes and 42 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughAdds an ChangesInternal error code, CachedTable filter scoping, and DB error preservation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
errors/errors.go (1)
90-94: ⚡ Quick winAdd test coverage for the new
IsInternalpredicate.
IsInternalis exported and part of the same predicate contract asIsNotFound/IsAlreadyExists; adding a small assertion inerrors/errors_test.gowould lock this behavior and prevent regressions.Suggested test addition
func Test_ErrorValidations(t *testing.T) { @@ err = Wrapf(NotFound, "%s", "test wrapf error from errors pkg") if !IsNotFound(err) { t.Errorf("expected error type Not Found") } + + err = Wrap(Internal, "internal failure") + if !IsInternal(err) { + t.Errorf("expected error type Internal") + } }🤖 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 `@errors/errors.go` around lines 90 - 94, The IsInternal function is exported and part of the error predicate contract, but it currently lacks test coverage. Add test cases in errors_test.go that verify IsInternal returns true when an error has the Internal error code and false otherwise, following the same testing pattern used for existing predicates like IsNotFound and IsAlreadyExists.
🤖 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.
Inline comments:
In `@table/cached_generic.go`:
- Around line 224-227: The error handling for the Count call in the filter
validation block and the eager-load block are currently wrapping all failures
with fixed error codes (InvalidArgument and Unknown respectively), which masks
the actual error types for transient failures like storage, auth, or network
errors. Instead of always wrapping with a fixed error code, check if the error
returned from col.Count is already a properly classified error and preserve its
error code. Only apply the InvalidArgument wrap if the error genuinely indicates
a filter validation problem. Apply the same approach to the eager-load error
handling to preserve the original error codes rather than always wrapping as
Unknown. This ensures that transient infrastructure failures are properly
distinguishable from actual validation errors.
---
Nitpick comments:
In `@errors/errors.go`:
- Around line 90-94: The IsInternal function is exported and part of the error
predicate contract, but it currently lacks test coverage. Add test cases in
errors_test.go that verify IsInternal returns true when an error has the
Internal error code and false otherwise, following the same testing pattern used
for existing predicates like IsNotFound and IsAlreadyExists.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6b8622eb-ec5b-418e-9692-7e8e175a463e
📒 Files selected for processing (4)
errors/const.goerrors/errors.gotable/cached_generic.gotable/generic.go
Address CodeRabbit review feedback: 1. Count preflight (InitializeWithConfig): wrapping all Count errors as InvalidArgument misclassified transient DB failures. Now uses the same GetErrCode pattern as Find methods — pass through typed errors, wrap unrecognized errors as Internal. 2. Eager-load (InitializeWithConfig): wrapping as Unknown was inconsistent with Find methods which wrap as Internal. Fixed to match. 3. Add test coverage for the new IsInternal predicate in errors_test.go, following the existing pattern for IsNotFound/IsAlreadyExists.
Summary
Table.Find,FindMany,FindManyWithOptsand the equivalentCachedTable.DBFind,DBFindMany,DBFindManyWithOptsunconditionally wrapped every error from the db layer asNotFound, destroying the error code thatinterpretMongoErrorhad already set correctly.This caused callers using
coreerrors.IsNotFound(err)to treat transient storage failures (connection resets, timeouts, auth failures) as genuine "document does not exist" results.Root cause
The db layer's
interpretMongoErroralready correctly mapsmongo.ErrNoDocuments→NotFoundand passes other errors through with no error code. The Table layer then re-wrapped everything asNotFound, making transient failures indistinguishable from true misses.Fix
If the error from the db layer already carries a recognized error code (e.g.,
NotFoundfrominterpretMongoErrorforErrNoDocuments), pass it through unchanged. Otherwise wrap asInternalso callers can distinguish transient failures from true misses.Changes
errors/const.go: AddInternalerror code (6)errors/errors.go: AddIsInternalhelpertable/generic.go: FixFind,FindMany,FindManyWithOptstable/cached_generic.go: FixDBFind,DBFindMany,DBFindManyWithOptsAffected methods (6 total)
TableFindNotFoundInternalTableFindManyNotFoundTableFindManyWithOptsNotFoundCachedTableDBFindNotFoundCachedTableDBFindManyNotFoundCachedTableDBFindManyWithOptsNotFoundImpact on consumers
Once this fix lands, existing consumers' transient-failure branches become reachable without any code changes on their side:
Reconcilepath atcoreerrors.IsNotFound(err)will correctly retry on transient DB failures instead of silently dropping the keyIsNotFoundcheck now only triggers on genuine misses (behavior unchanged since re-upsert is idempotent)FindManyerrors are already fatal to boot — behavior unchangederrors.IsNotFound(err)check for cache eviction now correctly distinguishes deletes from transient failuresBackward compatibility
IsNotFound(err)still returnstruefor genuine missing documents — no consumer behavior change on the happy pathInternalerror code andIsInternalhelper are additive — no breaking changesFindOnefor missing docs returnsErrNoDocuments→NotFound(same as before)Fixes agentic-core/core#48
Summary by CodeRabbit
New Features
Improvements