fix(rpc): catch billing resolution errors in getBilling() to enable free-tier fallback - #790
superlog-app[bot] wants to merge 1 commit into
Conversation
…ree-tier fallback Delivery-Id: d84dc55ddc9d5958a0986918622006a376305d7868aeb4c89966c85fea36d5bf Delivery-Base: staging
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
The latest updates on your projects. Learn more about Unkey Deploy
|
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
Greptile SummaryThis PR catches billing-owner resolution failures in the RPC context and memoizes an undefined result so callers can use their existing free-tier behavior.
Confidence Score: 4/5The PR should not merge as the complete remediation described because Catching Files Needing Attention: packages/rpc/src/orpc.ts Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[getUsage] --> B[context.getBilling]
B --> C{Billing lookup succeeds?}
C -->|Yes| D[Use resolved customer]
C -->|No| E[Catch and return undefined]
E --> F[Fall back to user customer ID]
D --> G[getAutumn.check]
F --> G
G --> H{AUTUMN_SECRET_KEY set?}
H -->|Yes| I[Return usage]
H -->|No| J[Throw internal RPC error]
Reviews (1): Last reviewed commit: "fix(rpc): catch billing resolution error..." | Re-trigger Greptile |
| } catch (error) { | ||
| logger.warn( | ||
| { error }, | ||
| "Failed to resolve billing owner; falling back to free tier" | ||
| ); | ||
| } |
There was a problem hiding this comment.
When AUTUMN_SECRET_KEY is missing, this catch makes context.getBilling() return undefined, but getUsage then calls getAutumn().check() directly. That call throws the same missing-secret error and is converted into an internal RPC error, so local environments still cannot retrieve usage through the intended free-tier fallback. The fallback must also cover or avoid that second Autumn call.
| } catch (error) { | ||
| logger.warn( | ||
| { error }, | ||
| "Failed to resolve billing owner; falling back to free tier" | ||
| ); | ||
| } | ||
| billingResolved = true; |
There was a problem hiding this comment.
Fallback behavior lacks coverage
The new exception-to-free-tier behavior has no direct test coverage. Existing procedure tests inject mocked getBilling implementations instead of invoking this closure, so regressions in the missing-secret fallback, warning, or resolved-state behavior could go unnoticed. Please add focused tests that cover returning undefined, logging the fallback, and avoiding another lookup on later calls.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
When
AUTUMN_SECRET_KEYis not set (e.g., developer local environments), calls togetBillingContextandgetUsagethrow an unhandledError: AUTUMN_SECRET_KEY is not setinstead of returning a graceful free-tier response. This surfaces as noisy ERROR-level log entries in Superlog and likely shows an error state in the billing UI instead of defaulting to the free tier.Root Cause
getBilling()inpackages/rpc/src/orpc.tsdeclares return typePromise<BillingOwner | undefined>— signaling intent to returnundefinedwhen billing is unavailable — but its call togetBillingOwner()is not wrapped in any error handler. WhengetAutumn()→createClient()throws becauseAUTUMN_SECRET_KEYis missing, the exception propagates up through every handler that callscontext.getBilling(), bypassing the explicit free-tier fallback (if (!customerId) return { planId: "free", ... }) and the surrounding try/catch that both exist ingetBillingContextfor exactly this scenario.Remediation
Wrap the
getBillingOwner()calls insidegetBilling()with try/catch. On failure, log a warning (not an error), leavebillingCacheasundefined, and setbillingResolved = trueto prevent retries. All calling handlers already guard withif (billing)and have free-tier fallbacks — this change lets those paths execute as intended.Related incident: b9496c9c-385f-4d6d-8280-6d62e105d93c
Was this PR helpful? Leave feedback — goes straight to the Superlog team.
Summary by cubic
Fixes an unhandled error in
getBilling()whenAUTUMN_SECRET_KEYis missing, so callers now fall back to the free tier instead of throwing. The function now catches resolution errors, logs a warning, and marks billing as resolved to avoid retries.Written for commit 6b2ec39. Summary will update on new commits.