feat(api-db): count transaction rollback failures#4117
Conversation
Transaction rollback failures now emit one Event from both explicit cleanup and the error path in WithTransaction. A bounded trigger distinguishes the two paths, while the caller location, static context, and rollback error stay log-only. The original closure error still wins, so this adds visibility without changing transaction return behavior. This supports NVIDIA#4108 Signed-off-by: Chet Nichols III <chetn@nvidia.com>
Summary by CodeRabbit
WalkthroughTransaction rollback failures now emit instrumented events and metrics for explicit cleanup and transaction-closure error paths. Tests validate event metadata and counter increments, and the new counter is documented. ChangesTransaction rollback instrumentation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant TransactionAPI
participant PgPool
participant RollbackRecorder
participant Instrumentation
TransactionAPI->>RollbackRecorder: record ExplicitCleanup rollback failure
PgPool->>RollbackRecorder: record ClosureError rollback failure
RollbackRecorder->>Instrumentation: emit event and increment counter
Instrumentation-->>TransactionAPI: rollback failure metadata
Instrumentation-->>PgPool: rollback failure metadata
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full_review, thanks! |
|
🐇🔍 ✅ Action performedFull review finished. |
|
🌿 Preview your docs: https://nvidia-preview-pull-request-4117.docs.buildwithfern.com/infra-controller |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/api-db/src/lib.rs (1)
988-995: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy liftExercise the rollback paths, not only the event payload.
This test directly calls
emit(DatabaseTransactionRollbackFailed::new(...)); it passes even if either rollback branch stops recording failures, and it bypassesDatabaseError::txn_rollback. Retain this event-contract test, but add cases that induce rollback failure throughrollback_or_logandwith_txn.As per path instructions, prefer findings about behavior, concurrency, resource lifetimes, and missing tests over style-only comments.
🤖 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 `@crates/api-db/src/lib.rs` around lines 988 - 995, Add integration cases that trigger rollback failures through both rollback branches, using rollback_or_log and with_txn, rather than only constructing DatabaseTransactionRollbackFailed directly. Keep the existing event-payload contract test, and verify each induced failure records the expected rollback-failure behavior/event through the actual DatabaseError::txn_rollback path.Source: Path instructions
🤖 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 `@crates/api-db/src/lib.rs`:
- Around line 988-995: Add integration cases that trigger rollback failures
through both rollback branches, using rollback_or_log and with_txn, rather than
only constructing DatabaseTransactionRollbackFailed directly. Keep the existing
event-payload contract test, and verify each induced failure records the
expected rollback-failure behavior/event through the actual
DatabaseError::txn_rollback path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: e3018256-3365-44c1-a451-0804b4ae021e
📒 Files selected for processing (2)
crates/api-db/src/lib.rsdocs/observability/core_metrics.md
Explicit transaction cleanup already warned when rollback failed, while
WithTransactiondiscarded a rollback failure after a closure returned an error. Both paths can leave the database result uncertain, but only one was visible and neither was countable.So, both branches now emit
DatabaseTransactionRollbackFailed. A boundedtriggerdistinguishes explicit cleanup from closure-error cleanup, while the caller location, static context, and rollback error stay log-only. The original closure error still wins, so transaction return behavior is unchanged.The table-driven Event contract covers both trigger values and verifies the warning fields and counter labels.
Tests added!
Related issues
This supports #4108
Part of #3169
Type of Change
Breaking Changes
Testing
Unit tests added/updated
Integration tests added/updated
Manual testing performed
No testing required (docs, internal refactor, etc.)
cargo test -p carbide-api-db database_transaction_rollback_failures_log_and_count_by_trigger --libcargo make clippycargo make carbide-lintscargo xtask check-workspace-depscargo make check-licensescargo make check-bansgit diff --check origin/mainAdditional Notes
The test intentionally exercises the Event contract rather than forcing a live SQLx backend to terminate during rollback; manufacturing that failure would couple a unit test to brittle driver behavior. Production wiring covers both existing rollback branches, and the primary transaction error remains unchanged.