Error Handling
Handle errors gracefully in your Pelago integration.
Error Response Format
All API errors follow a consistent format:
{
"error": {
"type": "invalid_request_error",
"code": "missing_parameter",
"message": "The 'amount' parameter is required",
"param": "amount",
"doc_url": "https://docs.pelago.tech/errors#missing_parameter"
}
}
HTTP Status Codes
| Code | Description | Action |
|---|---|---|
200 | Success | Process response |
201 | Created | Resource created |
400 | Bad Request | Fix request parameters |
401 | Unauthorized | Check API keys |
403 | Forbidden | Check permissions |
404 | Not Found | Check resource ID |
409 | Conflict | Handle idempotency |
422 | Unprocessable | Fix validation errors |
429 | Rate Limited | Slow down requests |
500 | Server Error | Retry with backoff |
503 | Service Unavailable | Retry later |
Error Types
authentication_error
Invalid or missing API credentials.
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid API key provided"
}
}
Solution:
// Check API key format
if (!apiKey.startsWith('pk_')) {
throw new Error('Invalid API key format');
}
// Verify keys are set
if (!process.env.PELAGO_API_KEY) {
throw new Error('PELAGO_API_KEY not configured');
}
invalid_request_error
Request parameters are invalid or missing.
{
"error": {
"type": "invalid_request_error",
"code": "invalid_amount",
"message": "Amount must be greater than 0",
"param": "amount"
}
}
Common Codes:
| Code | Description |
|---|---|
missing_parameter | Required field missing |
invalid_parameter | Field value invalid |
invalid_amount | Amount <= 0 or too large |
invalid_currency | Unsupported currency |
invalid_network | Unsupported network |
invalid_wallet | Malformed wallet address |
rate_limit_error
Too many requests.
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Retry after 60 seconds"
}
}
Solution:
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.type === 'rate_limit_error') {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(r => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
payment_error
Payment-specific errors.
| Code | Description | Recovery |
|---|---|---|
payment_expired | Payment timed out | Create new payment |
payment_already_completed | Already paid | No action needed |
insufficient_funds | Customer lacks funds | Customer adds funds |
network_error | Blockchain issue | Retry later |
wallet_error | Invalid wallet | Fix wallet address |
api_error
Server-side issues.
{
"error": {
"type": "api_error",
"code": "internal_error",
"message": "An internal error occurred"
}
}
Solution: Retry with exponential backoff.
SDK Error Handling
JavaScript
import { PelagoClient, PelagoError } from '@pelago/sdk';
try {
const payment = await pelago.payments.create({
amount: 100,
currency: 'USD',
// ...
});
} catch (error) {
if (error instanceof PelagoError) {
switch (error.type) {
case 'authentication_error':
console.error('Check your API keys');
break;
case 'invalid_request_error':
console.error('Invalid param:', error.param);
break;
case 'rate_limit_error':
console.error('Slow down, retrying...');
await delay(60000);
// Retry
break;
case 'payment_error':
console.error('Payment error:', error.code);
break;
default:
console.error('Unexpected error:', error.message);
}
} else {
// Network error or other issue
console.error('Connection error:', error);
}
}
Python
from pelago import PelagoClient, PelagoError
from pelago.errors import (
AuthenticationError,
InvalidRequestError,
RateLimitError,
PaymentError
)
try:
payment = pelago.payments.create(
amount=100,
currency='USD',
# ...
)
except AuthenticationError as e:
print('Check your API keys')
except InvalidRequestError as e:
print('Invalid param:', e.param)
except RateLimitError:
print('Rate limited, retrying...')
time.sleep(60)
# Retry
except PaymentError as e:
print('Payment error:', e.code)
except PelagoError as e:
print('Unexpected error:', e.message)
Validation Errors
For validation errors, check all failed fields:
{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "Request validation failed",
"errors": [
{
"param": "amount",
"message": "Amount must be greater than 0"
},
{
"param": "currency",
"message": "Currency must be uppercase"
}
]
}
}
Handling:
catch (error) {
if (error.code === 'validation_failed') {
for (const fieldError of error.errors) {
console.error(`${fieldError.param}: ${fieldError.message}`);
}
}
}
Network Error Handling
async function createPaymentWithRetry(params: PaymentParams) {
const maxRetries = 3;
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await pelago.payments.create(params);
} catch (error) {
lastError = error;
// Don't retry client errors
if (error.type === 'invalid_request_error') {
throw error;
}
// Don't retry authentication errors
if (error.type === 'authentication_error') {
throw error;
}
// Retry server errors and network issues
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retry ${attempt}/${maxRetries} in ${delay}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
}
throw lastError;
}
Error Logging Best Practices
import { PelagoError } from '@pelago/sdk';
function logError(error: Error, context: object) {
if (error instanceof PelagoError) {
console.error({
type: 'pelago_error',
errorType: error.type,
code: error.code,
message: error.message,
param: error.param,
requestId: error.requestId, // For support
...context
});
} else {
console.error({
type: 'unknown_error',
message: error.message,
stack: error.stack,
...context
});
}
}
// Usage
try {
await pelago.payments.create(params);
} catch (error) {
logError(error, {
action: 'create_payment',
orderId: params.metadata.orderId
});
throw error;
}