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
| Code | Status | Description | Action |
|---|---|---|---|
unauthorized | 401 | Missing or invalid API key | Check API key |
api_key_invalid | 401 | API key format is wrong | Verify key format |
api_key_revoked | 401 | API key has been revoked | Generate new key |
api_key_expired | 401 | API key has expired | Renew key |
forbidden | 403 | Action not allowed | Check permissions |
tier_restriction | 403 | Feature not available on plan | Upgrade plan |
webhook_limit_reached | 403 | Max webhooks for tier | Delete unused webhooks |
invalid_request | 400 | Malformed request | Check request body |
invalid_url | 400 | URL is invalid or unreachable | Validate URL |
invalid_mode | 400 | Unknown audit mode | Use basic/standard/deep |
missing_parameter | 400 | Required field missing | Check required fields |
not_found | 404 | Resource doesn't exist | Check ID |
job_not_found | 404 | Audit job not found | Verify job_id |
quota_exceeded | 429 | Out of credits | Wait for reset or upgrade |
rate_limit_exceeded | 429 | Too many requests | Wait and retry |
concurrent_limit_exceeded | 429 | Too many parallel audits | Queue requests |
internal_error | 500 | Server error | Retry later |
timeout | 500 | Request timed out | Retry later |
For the complete error reference, see API Error Codes.
Related
- API Error Codes - Complete error code reference
- Client Setup - Configure retry behavior
- Audit Methods - Methods that may throw errors
Was this page helpful?