Skip to content

task: normalize Soroban RPC errors to stable API codes for /api/billing/deduct#372

Open
icodeBisola wants to merge 1 commit into
CalloraOrg:mainfrom
icodeBisola:task/soroban-error-normalization
Open

task: normalize Soroban RPC errors to stable API codes for /api/billing/deduct#372
icodeBisola wants to merge 1 commit into
CalloraOrg:mainfrom
icodeBisola:task/soroban-error-normalization

Conversation

@icodeBisola
Copy link
Copy Markdown

Summary

Closes #319

Maps Soroban RPC failures in sorobanBilling.ts to stable error types so /api/billing/deduct always returns predictable HTTP status codes.

Changes

src/services/sorobanBilling.ts

  • Added SorobanRpcErrorCategory type: INSUFFICIENT_BALANCE | TIMEOUT | CONTRACT_ERROR | NETWORK_ERROR
  • Added SorobanRpcError class (extends Error) carrying a category field
  • Added classifyError(message) helper that maps error message keywords to categories
  • All throws inside invoke() now produce SorobanRpcError with the correct category (HTTP errors → NETWORK_ERROR, missing result → NETWORK_ERROR, simulation errors → classified by message, abort/timeout → TIMEOUT)

src/routes/billing.ts

  • Imported SorobanRpcError, BadGatewayError, GatewayTimeoutError
  • /deduct catch block maps SorobanRpcError categories:
    • INSUFFICIENT_BALANCEPaymentRequiredError (402)
    • TIMEOUTGatewayTimeoutError (504)
    • CONTRACT_ERROR / NETWORK_ERRORBadGatewayError (502)
  • result.success === false block also maps error message keywords to the same stable codes

src/services/sorobanBilling.test.ts

  • Added 7 new tests covering all SorobanRpcError categories
  • All 12 tests pass (5 original + 7 new)

Acceptance Criteria

Scenario HTTP Status Code
Insufficient balance 402 INSUFFICIENT_BALANCE
RPC timeout / abort 504 SOROBAN_RPC_TIMEOUT
Contract error 502 SOROBAN_RPC_ERROR
Network / HTTP error 502 SOROBAN_RPC_ERROR

Test Output

PASS src/services/sorobanBilling.test.ts
  buildSorobanBalanceInvocation
    ✓ assembles a balance invocation for a user id
  buildSorobanDeductInvocation
    ✓ assembles a deduct invocation with optional idempotency key
  SorobanRpcBillingClient
    ✓ posts a balance invocation and normalizes the returned balance
    ✓ posts a deduct invocation and returns the transaction hash
    ✓ normalizes simulation failures returned by Soroban RPC
  SorobanRpcError categories
    ✓ classifies insufficient balance as INSUFFICIENT_BALANCE
    ✓ classifies insufficient funds as INSUFFICIENT_BALANCE
    ✓ classifies contract error as CONTRACT_ERROR
    ✓ classifies simulation failed as CONTRACT_ERROR
    ✓ classifies HTTP failure as NETWORK_ERROR
    ✓ classifies timeout/abort as TIMEOUT
    ✓ missing result in RPC response is classified as NETWORK_ERROR

Tests: 12 passed, 12 total

- Add SorobanRpcError class with SorobanRpcErrorCategory type to sorobanBilling.ts
- Classify RPC failures: INSUFFICIENT_BALANCE → 402, TIMEOUT → 504, CONTRACT_ERROR/NETWORK_ERROR → 502
- Update /api/billing/deduct handler to map SorobanRpcError categories to PaymentRequiredError, GatewayTimeoutError, BadGatewayError
- Add 7 tests covering all error categories (12 total, all passing)

Closes CalloraOrg#319
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Jun 1, 2026

@icodeBisola Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Normalize Soroban RPC errors in sorobanBilling.ts into stable API error codes for /api/billing/deduct

1 participant