Commit f997e3c
authored
fix(code-reviews): billing error classification (#1332)
## Summary
Billing errors from code reviews were being misclassified in two ways:
v1 billing errors arrived as `interrupted` and got normalized to
`cancelled` (hiding them from billing analytics), and v2 billing errors
had the real error message discarded by the wrapper, storing the generic
string `session.error` instead. This PR adds a `terminal_reason` column
to track failure categories, fixes both classification paths, posts
billing notices on PRs/MRs, and backfills ~13k historical rows.
Three layers of fixes:
- **Wrapper** (`cloud-agent-next`): passes the real billing error text
from `properties.error` instead of discarding it and forwarding just the
event type string.
- **normalizePayload** (status callback handler): detects billing
patterns in error messages when no explicit `terminalReason` is set,
reclassifying `cancelled` billing errors as `failed` with
`terminalReason: 'billing'`.
- **Orchestrator**: catches 402 billing errors from
`prepareSession`/`initiateSession`/`sendMessageV2`, tags them with
`terminalReason: 'billing'`, and prevents the sendMessage fallback from
retrying billing failures.
Also adds billing PR/MR comment notices, admin dashboard improvements
for billing vs. non-billing failure separation, and three backfill
migrations for historical data.
## Verification
- [x] `pnpm jest 'code-review-status.*route\.test'` — 17 tests pass (4
new: interrupted billing reclassification, failed billing inference,
non-billing interrupted preserved, explicit terminalReason preserved)
- [x] `pnpm typecheck` — passes across all workspace packages including
cloud-agent-next wrapper
- [x] Pre-push hooks passed (format, lint, typecheck)
## Visual Changes
N/A
## Reviewer Notes
- The v2 backfill migration (0057) uses exact `error_message =
'session.error'` matching rather than ILIKE patterns to avoid false
positives from branch names containing billing keywords.
- Migration 0056 already backfilled v1 `failed` billing rows (23,711
rows). Migration 0057 covers the remaining gaps: v1 `cancelled` billing
rows (~12,461) and v2 `session.error` rows (742).
- Deployment order matters: deploy the normalizePayload fix (Next.js)
first so it's ready to handle callbacks, then apply the backfill
migration, then deploy the wrapper fix (cloud-agent-next Worker).
- The `!terminalReason` guard in normalizePayload ensures the billing
inference only fires when no explicit reason was provided —
orchestrator-path billing errors (which already send `terminalReason:
'billing'`) are not double-handled.10 files changed
Lines changed: 14965 additions & 6 deletions
File tree
- cloud-agent-next/wrapper/src
- packages
- db/src
- migrations
- meta
- worker-utils/src
- src
- app/api/internal/code-review-status/[reviewId]
- lib/integrations/platforms
- github
- gitlab
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
273 | 273 | | |
274 | 274 | | |
275 | 275 | | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
276 | 298 | | |
277 | 299 | | |
278 | 300 | | |
| |||
367 | 389 | | |
368 | 390 | | |
369 | 391 | | |
370 | | - | |
| 392 | + | |
371 | 393 | | |
372 | 394 | | |
373 | 395 | | |
| |||
Lines changed: 23 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
0 commit comments