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,ErrorDetailschemas — /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"
}
}
}| Field | Description |
|---|---|
code | Machine-readable error code (e.g. VALIDATION_ERROR) |
type | Error category (e.g. validation_error) |
message | Human-readable description |
requestId | Unique request identifier — use for support and logging |
details | Field-level validation messages (when type is validation_error) |
Error Types
| Type | HTTP Status | SDK Class |
|---|---|---|
validation_error | 400 | ValidationError |
authentication_error | 401 | AuthenticationError |
authorization_error | 403 | AuthorizationError |
resource_error | 404 | NotFoundError |
conflict_error | 409 | ConflictError |
idempotency_error | 409 | ConflictError |
business_rule_error | 422 | ConflictError |
rate_limit_error | 429 | RateLimitError |
internal_error | 500 | InternalError |
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
| Condition | Retry? | Strategy |
|---|---|---|
| Network error | Yes | Exponential backoff (SDK default: 2 retries) |
| HTTP 5xx | Yes | Exponential backoff |
| HTTP 429 | Yes | Respect Retry-After header |
| HTTP 400 | No | Fix the request |
| HTTP 401 | No | Fix authentication |
| HTTP 403 | No | Fix permissions |
| HTTP 404 | No | Check resource ID |
| HTTP 409 | No | Handle conflict (new idempotency key or accept replay) |
| HTTP 422 | No | Handle business rule |
| Timeout / abort | No | User-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,
});
}Related
- Authentication — 401/403 codes
- Idempotency — 409 idempotency conflicts
- Best Practices — retry and logging patterns
- FAQ — common error scenarios
Was this page helpful?
error-handling