Developer Docs

Error Handling

Understand API error codes and retry strategies.

All BSync Public API errors follow a unified contract. The SDK maps these to typed error classes automatically.

OpenAPI: ErrorResponse, ErrorDetail schemas — /docs/api-reference

Error Contract

Every error response:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "type": "validation_error",
    "message": "Amount must be greater than 0",
    "requestId": "req_abc123",
    "details": {
      "amount": "must be a positive number"
    }
  }
}
FieldDescription
codeMachine-readable error code (e.g. VALIDATION_ERROR)
typeError category (e.g. validation_error)
messageHuman-readable description
requestIdUnique request identifier — use for support and logging
detailsField-level validation messages (when type is validation_error)

Error Types

TypeHTTP StatusSDK Class
validation_error400ValidationError
authentication_error401AuthenticationError
authorization_error403AuthorizationError
resource_error404NotFoundError
conflict_error409ConflictError
idempotency_error409ConflictError
business_rule_error422ConflictError
rate_limit_error429RateLimitError
internal_error500InternalError

Network failures, timeouts, and aborts throw BSyncConnectionError (not an API error).

Examples by Status

401 — Authentication Error

{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "type": "authentication_error",
    "message": "The provided API key is invalid.",
    "requestId": "req_auth001",
    "details": {}
  }
}

Action: Check your API key. Ensure it starts with bsync_test_* or bsync_live_*.

404 — Not Found

{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "type": "resource_error",
    "message": "The requested resource was not found.",
    "requestId": "req_nf001",
    "details": {}
  }
}

Action: Verify the paymentId exists and matches your API key environment.

409 — Conflict

{
  "success": false,
  "error": {
    "code": "IDEMPOTENCY_CONFLICT",
    "type": "idempotency_error",
    "message": "Idempotency-Key was already used with a different request.",
    "requestId": "req_conf001",
    "details": {}
  }
}

Action: Use a new idempotency key, or send the same body with the same key to replay.

422 — Business Rule

{
  "success": false,
  "error": {
    "code": "PAYMENT_UNDER_REVIEW",
    "type": "business_rule_error",
    "message": "This payment is under manual review.",
    "requestId": "req_br001",
    "details": {}
  }
}

Action: Wait for PAYMENT_REVIEW_APPROVED or PAYMENT_REVIEW_REJECTED webhook.

429 — Rate Limit

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "type": "rate_limit_error",
    "message": "Rate limit exceeded for this API key.",
    "requestId": "req_rl001",
    "details": {}
  }
}

Response includes Retry-After header. SDK RateLimitError exposes retryAfter in seconds.

500 — Internal Error

{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "type": "internal_error",
    "message": "An unexpected error occurred.",
    "requestId": "req_int001",
    "details": {}
  }
}

Action: Retry with backoff. Contact support with requestId if persistent.

SDK Error Handling

import {
  BSync,
  ValidationError,
  AuthenticationError,
  NotFoundError,
  ConflictError,
  RateLimitError,
  InternalError,
  BSyncConnectionError,
} from "@bsync/node-sdk";
 
try {
  await bsync.paymentIntents.create({ amount: 150, currency: "EGP", redirectDelay: 3 });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Invalid request:", error.details);
  } else if (error instanceof RateLimitError) {
    console.error("Rate limited. Retry after:", error.retryAfter);
  } else if (error instanceof BSyncConnectionError) {
    console.error("Network error:", error.message);
  } else if (error instanceof BSyncError) {
    console.error(error.code, error.requestId, error.message);
  }
}

Every BSyncError subclass exposes: code, type, requestId, statusCode, details, message.

Retry Strategy

ConditionRetry?Strategy
Network errorYesExponential backoff (SDK default: 2 retries)
HTTP 5xxYesExponential backoff
HTTP 429YesRespect Retry-After header
HTTP 400NoFix the request
HTTP 401NoFix authentication
HTTP 403NoFix permissions
HTTP 404NoCheck resource ID
HTTP 409NoHandle conflict (new idempotency key or accept replay)
HTTP 422NoHandle business rule
Timeout / abortNoUser-initiated or increase timeout

The SDK handles retries automatically for network errors, 5xx, and 429. Configure with maxRetries:

const bsync = new BSync({
  apiKey: process.env.BSYNC_API_KEY,
  maxRetries: 3,
  timeout: 30_000,
});

Logging Errors

Always log requestId when reporting errors:

catch (error) {
  logger.error("BSync API error", {
    code: error.code,
    requestId: error.requestId,
    statusCode: error.statusCode,
    message: error.message,
  });
}

Was this page helpful?

error-handling

Command Palette

Search for a command to run...