# Error Handling

Handle errors gracefully with HivePay's typed error system.


# HivePayError

All API errors are thrown as HivePayError instances:

import { HivePay, HivePayError, isHivePayError } from '@hivepay/client';

try {
  await hivepay.payments.get('invalid-id');
} catch (error) {
  if (isHivePayError(error)) {
    console.log(error.code);       // Error code
    console.log(error.statusCode); // HTTP status
    console.log(error.message);    // Error message
  }
}

# Properties

Property Type Description
code ErrorCode Error type identifier
statusCode number HTTP status code
message string Human-readable message

# Error Codes

Code Status Description
NETWORK_ERROR - Network request failed or timed out
API_ERROR varies General API error
AUTHENTICATION_ERROR 401 Invalid or missing API key
FORBIDDEN_ERROR 403 Insufficient permissions
NOT_FOUND_ERROR 404 Resource not found
VALIDATION_ERROR 400 Invalid request parameters
RATE_LIMIT_ERROR 429 Too many requests
SERVER_ERROR 5xx Server-side error

# Type Guard

Use isHivePayError to safely check error type:

import { isHivePayError } from '@hivepay/client';

try {
  await hivepay.payments.create({ ... });
} catch (error) {
  if (isHivePayError(error)) {
    // TypeScript knows error is HivePayError
    handleHivePayError(error);
  } else {
    // Unknown error
    throw error;
  }
}

# Error Type Methods

HivePayError provides methods to check error type:

if (isHivePayError(error)) {
  if (error.isNotFound()) {
    // 404 - Resource not found
    console.log('Payment not found');
  } else if (error.isAuthError()) {
    // 401 - Authentication failed
    console.log('Invalid API key');
  } else if (error.isValidation()) {
    // 400 - Validation error
    console.log('Invalid data:', error.message);
  } else if (error.isRateLimited()) {
    // 429 - Rate limited
    console.log('Too many requests, retry later');
  } else if (error.isForbidden()) {
    // 403 - Forbidden
    console.log('Access denied');
  } else if (error.isServerError()) {
    // 5xx - Server error
    console.log('Server error, retry later');
  }
}

# Available Methods

Method Returns true for
isNotFound() NOT_FOUND_ERROR (404)
isAuthError() AUTHENTICATION_ERROR (401)
isValidation() VALIDATION_ERROR (400)
isRateLimited() RATE_LIMIT_ERROR (429)
isForbidden() FORBIDDEN_ERROR (403)
isServerError() SERVER_ERROR (5xx)
isNetworkError() NETWORK_ERROR

# Handling Specific Errors

# Authentication Errors

try {
  await hivepay.payments.create({ ... });
} catch (error) {
  if (isHivePayError(error) && error.isAuthError()) {
    // API key is invalid or expired
    // Redirect to login or refresh key
    await refreshApiKey();
  }
}

# Not Found Errors

try {
  const payment = await hivepay.payments.get(paymentId);
} catch (error) {
  if (isHivePayError(error) && error.isNotFound()) {
    // Payment doesn't exist
    return null;
  }
  throw error;
}

# Validation Errors

try {
  await hivepay.payments.create({
    amount: 'invalid',
    currency: 'USD',  // Invalid currency
    description: ''
  });
} catch (error) {
  if (isHivePayError(error) && error.isValidation()) {
    // Show error to user
    showError(error.message);
  }
}

# Rate Limiting

async function createPaymentWithRetry(data: CreatePaymentData, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await hivepay.payments.create(data);
    } catch (error) {
      if (isHivePayError(error) && error.isRateLimited()) {
        if (attempt < maxRetries) {
          // Wait before retry (exponential backoff)
          await sleep(1000 * Math.pow(2, attempt));
          continue;
        }
      }
      throw error;
    }
  }
}

# Network Errors

try {
  await hivepay.payments.create({ ... });
} catch (error) {
  if (isHivePayError(error) && error.isNetworkError()) {
    // Connection failed or timed out
    showError('Unable to connect. Please check your internet connection.');
  }
}

# Complete Example

import {
  HivePay,
  isHivePayError,
  type CreatePaymentOptions
} from '@hivepay/client';

const hivepay = new HivePay({ apiKey: process.env.HIVEPAY_API_KEY! });

async function createPayment(options: CreatePaymentOptions) {
  try {
    const payment = await hivepay.payments.create(options);
    return { success: true, payment };
  } catch (error) {
    if (!isHivePayError(error)) {
      // Unknown error - rethrow
      throw error;
    }

    // Handle specific error types
    if (error.isAuthError()) {
      return {
        success: false,
        error: 'Authentication failed. Check your API key.'
      };
    }

    if (error.isValidation()) {
      return {
        success: false,
        error: `Invalid data: ${error.message}`
      };
    }

    if (error.isRateLimited()) {
      return {
        success: false,
        error: 'Too many requests. Please wait and try again.'
      };
    }

    if (error.isServerError()) {
      return {
        success: false,
        error: 'Server error. Please try again later.'
      };
    }

    if (error.isNetworkError()) {
      return {
        success: false,
        error: 'Network error. Check your connection.'
      };
    }

    // Fallback for unhandled error codes
    return {
      success: false,
      error: error.message
    };
  }
}

# TypeScript Types

type ErrorCode =
  | 'NETWORK_ERROR'
  | 'API_ERROR'
  | 'AUTHENTICATION_ERROR'
  | 'FORBIDDEN_ERROR'
  | 'NOT_FOUND_ERROR'
  | 'VALIDATION_ERROR'
  | 'RATE_LIMIT_ERROR'
  | 'SERVER_ERROR';

class HivePayError extends Error {
  readonly code: ErrorCode;
  readonly statusCode: number;

  isNotFound(): boolean;
  isAuthError(): boolean;
  isValidation(): boolean;
  isRateLimited(): boolean;
  isForbidden(): boolean;
  isServerError(): boolean;
  isNetworkError(): boolean;
}

function isHivePayError(error: unknown): error is HivePayError;