Skip to main content

Error Handling

Learn how to handle errors in the ZenPays SDK.

Error Types

The SDK provides specific error classes for different scenarios:

Error ClassHTTP StatusDescription
ZenPaysErrorVariousBase error class
AuthenticationError401Invalid API key
AuthorizationError403Insufficient permissions
NotFoundError404Resource not found
ValidationError400Invalid input data
RateLimitError429Rate limit exceeded
NetworkError-Network connectivity issues
PaymentError402Payment processing failed
ConfigurationError-SDK misconfiguration

Basic Error Handling

import {
AuthenticationError,
NotFoundError,
ValidationError,
ZenPaysError,
} from 'zenpays'

try {
await zenpays.payments.createPaymentIntent({
amount: 1000,
currency: 'USD',
})
}
catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key. Check your credentials.')
}
else if (error instanceof ValidationError) {
console.error('Validation failed:', error.message)
console.error('Fields:', error.fields)
}
else if (error instanceof NotFoundError) {
console.error('Resource not found')
}
else if (error instanceof ZenPaysError) {
console.error(`API Error [${error.code}]: ${error.message}`)
console.error('Status:', error.status)
console.error('Details:', error.details)
}
else {
throw error // Re-throw unexpected errors
}
}

Error Properties

All ZenPays errors include:

interface ZenPaysError extends Error {
message: string // Human-readable message
code?: string // Error code (e.g., 'VALIDATION_ERROR')
status?: number // HTTP status code
details?: string // Additional details
}

Rate Limiting

Handle rate limits gracefully:

import { RateLimitError } from 'zenpays'

async function makeRequestWithRetry(fn: () => Promise<any>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
}
catch (error) {
if (error instanceof RateLimitError && i < maxRetries - 1) {
const delay = error.retryAfter ?? (2 ** i * 1000)
console.log(`Rate limited. Retrying in ${delay}ms...`)
await new Promise(resolve => setTimeout(resolve, delay))
}
else {
throw error
}
}
}
}

// Usage
const intent = await makeRequestWithRetry(() =>
zenpays.payments.createPaymentIntent({ amount: 1000, currency: 'USD' })
)

Network Errors

Handle network connectivity issues:

import { NetworkError } from 'zenpays'

try {
await zenpays.payments.createPaymentIntent({
amount: 1000,
currency: 'USD',
})
}
catch (error) {
if (error instanceof NetworkError) {
if (error.message === 'Request timeout') {
console.error('Request timed out. Try again later.')
}
else {
console.error('Network error. Check your connection.')
}
}
}

Payment Errors

Handle payment-specific errors:

import { PaymentError } from 'zenpays'

try {
await zenpays.payments.confirmPayment('pi_xxx', {
customerDetails: { ... },
paymentMethodDetails: { ... },
})
} catch (error) {
if (error instanceof PaymentError) {
console.error('Payment failed:', error.message)
console.error('Intent ID:', error.paymentIntentId)
// Show user-friendly message
}
}

Validation Errors

Handle validation errors with field-level details:

import { ValidationError } from 'zenpays'

try {
await zenpays.customers.create({
email: 'invalid-email',
name: '',
})
}
catch (error) {
if (error instanceof ValidationError) {
console.error('Validation errors:')
if (error.fields) {
for (const [field, messages] of Object.entries(error.fields)) {
console.error(` ${field}: ${messages.join(', ')}`)
}
}
}
}

Best Practices

  1. Always catch errors - Don't let errors crash your application
  2. Use specific error types - Check for specific errors before generic ones
  3. Log error details - Include code, status, and details for debugging
  4. Show user-friendly messages - Don't expose technical details to users
  5. Implement retry logic - Handle transient errors automatically
  6. Monitor errors - Track error rates in production

Example: Complete Error Handler

import {
AuthenticationError,
AuthorizationError,
NetworkError,
NotFoundError,
PaymentError,
RateLimitError,
ValidationError,
ZenPaysError,
} from 'zenpays'

function handleZenPaysError(error: unknown): {
message: string
shouldRetry: boolean
retryDelay?: number
} {
if (error instanceof AuthenticationError) {
return { message: 'Invalid API key', shouldRetry: false }
}

if (error instanceof AuthorizationError) {
return { message: 'Access denied', shouldRetry: false }
}

if (error instanceof NotFoundError) {
return { message: 'Resource not found', shouldRetry: false }
}

if (error instanceof ValidationError) {
return { message: error.message, shouldRetry: false }
}

if (error instanceof RateLimitError) {
return {
message: 'Too many requests',
shouldRetry: true,
retryDelay: error.retryAfter ?? 5000,
}
}

if (error instanceof NetworkError) {
return { message: 'Network error', shouldRetry: true, retryDelay: 1000 }
}

if (error instanceof PaymentError) {
return { message: 'Payment failed', shouldRetry: false }
}

if (error instanceof ZenPaysError) {
return { message: error.message, shouldRetry: false }
}

return { message: 'An unexpected error occurred', shouldRetry: false }
}