Skip to main content
VertaaUX Docs
SDK

Error Handling

Handle errors gracefully with the VertaaUX SDK

Error Handling

The SDK provides typed errors for clean error handling and control flow in your TypeScript applications.

Error Philosophy

The SDK throws typed errors that you can catch and handle based on the error code. This enables:

  • Graceful degradation - Handle specific errors differently
  • User feedback - Show meaningful messages to users
  • Retry logic - Automatically retry transient failures
  • Logging - Include request IDs for debugging

VertaaError Class

All SDK errors extend the VertaaError base class:

class VertaaError extends Error {
  code: string;        // Error code from API (e.g., 'quota_exceeded')
  message: string;     // Human-readable message
  statusCode: number;  // HTTP status code
  requestId?: string;  // Request ID for support
}

Basic Error Handling

Wrap SDK calls in try/catch to handle errors:

import { VertaaUX, VertaaError } from '@vertaaux/sdk';

const client = new VertaaUX({
  apiKey: process.env.VERTAA_API_KEY!,
});

try {
  const job = await client.audits.create({
    url: 'https://example.com',
  });
  console.log('Audit started:', job.job_id);
} catch (error) {
  if (error instanceof VertaaError) {
    console.error(`Error ${error.code}: ${error.message}`);
    console.error('Request ID:', error.requestId);
  } else {
    throw error; // Re-throw unexpected errors
  }
}

Error Code Handling

Handle specific error codes for different behaviors:

import { VertaaUX, VertaaError } from '@vertaaux/sdk';

async function createAuditWithHandling(url: string) {
  const client = new VertaaUX({
    apiKey: process.env.VERTAA_API_KEY!,
  });

  try {
    return await client.audits.create({ url });
  } catch (error) {
    if (error instanceof VertaaError) {
      switch (error.code) {
        case 'quota_exceeded':
          // User is out of credits
          console.log('Quota exceeded. Upgrade your plan for more audits.');
          throw new Error('Please upgrade your plan to continue auditing.');

        case 'rate_limit_exceeded':
          // Too many requests - wait and retry
          console.log('Rate limited. Waiting before retry...');
          await new Promise((r) => setTimeout(r, 60000)); // Wait 1 minute
          return await client.audits.create({ url }); // Retry

        case 'invalid_url':
          // Bad user input
          throw new Error(`Invalid URL: ${url}. Please enter a valid http/https URL.`);

        case 'unauthorized':
        case 'api_key_invalid':
          // Authentication issue
          console.error('API key is invalid or missing');
          throw new Error('Authentication failed. Check your API key.');

        default:
          // Unknown error
          console.error(`Unexpected error: ${error.code} - ${error.message}`);
          throw error;
      }
    }
    throw error;
  }
}

Common Error Patterns

Rate Limiting

Handle rate limits with automatic retry using the Retry-After header:

import { VertaaUX, VertaaError } from '@vertaaux/sdk';

async function createAuditWithRetry(
  client: VertaaUX,
  url: string,
  maxRetries = 3
) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.audits.create({ url });
    } catch (error) {
      if (
        error instanceof VertaaError &&
        error.code === 'rate_limit_exceeded' &&
        attempt < maxRetries - 1
      ) {
        // SDK already handles Retry-After internally,
        // but you can add extra backoff here
        const waitTime = Math.pow(2, attempt) * 1000;
        console.log(`Rate limited. Retrying in ${waitTime}ms...`);
        await new Promise((r) => setTimeout(r, waitTime));
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

The SDK has built-in retry logic for rate limits and server errors. Configure it via the retry option when creating the client.

Quota Management

Check quota before creating audits to provide better user experience:

import { VertaaUX, VertaaError } from '@vertaaux/sdk';

async function auditWithQuotaCheck(client: VertaaUX, url: string) {
  // Check quota first
  const quota = await client.getQuota();

  if (quota.credits_remaining === 0) {
    console.log(`Quota exhausted. Resets on ${quota.reset_date}`);
    throw new Error(
      `No credits remaining. Your quota resets on ${new Date(quota.reset_date).toLocaleDateString()}`
    );
  }

  console.log(`Credits remaining: ${quota.credits_remaining}/${quota.credits_total}`);

  // Proceed with audit
  return await client.audits.create({ url });
}

Invalid URL Handling

Validate URLs before making API calls:

function isValidUrl(url: string): boolean {
  try {
    const parsed = new URL(url);
    return parsed.protocol === 'http:' || parsed.protocol === 'https:';
  } catch {
    return false;
  }
}

async function createAuditSafe(client: VertaaUX, url: string) {
  // Validate locally first
  if (!isValidUrl(url)) {
    throw new Error(`Invalid URL format: ${url}`);
  }

  try {
    return await client.audits.create({ url });
  } catch (error) {
    if (error instanceof VertaaError && error.code === 'invalid_url') {
      // API rejected the URL (e.g., blocked domain, unreachable)
      throw new Error(`URL cannot be audited: ${error.message}`);
    }
    throw error;
  }
}

Network Errors

Handle network-level failures:

async function auditWithNetworkHandling(client: VertaaUX, url: string) {
  try {
    return await client.audits.create({ url });
  } catch (error) {
    // Network errors don't have error.code
    if (error instanceof TypeError && error.message.includes('fetch')) {
      console.error('Network error - check your internet connection');
      throw new Error('Unable to connect to VertaaUX. Please check your network.');
    }

    if (error instanceof VertaaError) {
      // API errors
      if (error.statusCode >= 500) {
        console.error('Server error - VertaaUX may be experiencing issues');
        throw new Error('VertaaUX service temporarily unavailable. Please try again.');
      }
    }

    throw error;
  }
}

Logging Errors

Include request IDs in logs for support:

import { VertaaUX, VertaaError } from '@vertaaux/sdk';

async function auditWithLogging(client: VertaaUX, url: string) {
  try {
    return await client.audits.create({ url });
  } catch (error) {
    if (error instanceof VertaaError) {
      // Log with all relevant details
      console.error('VertaaUX API Error:', {
        code: error.code,
        message: error.message,
        statusCode: error.statusCode,
        requestId: error.requestId,
        url,
        timestamp: new Date().toISOString(),
      });

      // For support tickets, include the request ID
      if (error.requestId) {
        console.error(
          `For support, reference request ID: ${error.requestId}`
        );
      }
    }
    throw error;
  }
}

Error Codes Reference

CodeStatusDescriptionAction
unauthorized401Missing or invalid API keyCheck API key
api_key_invalid401API key format is wrongVerify key format
api_key_revoked401API key has been revokedGenerate new key
api_key_expired401API key has expiredRenew key
forbidden403Action not allowedCheck permissions
tier_restriction403Feature not available on planUpgrade plan
webhook_limit_reached403Max webhooks for tierDelete unused webhooks
invalid_request400Malformed requestCheck request body
invalid_url400URL is invalid or unreachableValidate URL
invalid_mode400Unknown audit modeUse basic/standard/deep
missing_parameter400Required field missingCheck required fields
not_found404Resource doesn't existCheck ID
job_not_found404Audit job not foundVerify job_id
quota_exceeded429Out of creditsWait for reset or upgrade
rate_limit_exceeded429Too many requestsWait and retry
concurrent_limit_exceeded429Too many parallel auditsQueue requests
internal_error500Server errorRetry later
timeout500Request timed outRetry later

For the complete error reference, see API Error Codes.

Was this page helpful?

On this page