Error Handling
The Raptor SDK provides comprehensive error handling with typed exceptions and detailed error information.Error Types
RaptorAPIError
API errors (4xx, 5xx responses):Copy
import Raptor, { RaptorAPIError } from '@raptor-data/ts-sdk';
const raptor = new Raptor({ apiKey: process.env.RAPTOR_API_KEY });
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorAPIError) {
console.error(`API Error ${error.statusCode}: ${error.message}`);
console.error('Response:', error.response);
}
}
HTTP status code (400, 401, 404, etc.)
Error message from the API
Full API response body
RaptorError
Client-side errors (validation, network, etc.):Copy
import Raptor, { RaptorError } from '@raptor-data/ts-sdk';
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorError) {
console.error(`Client Error: ${error.message}`);
}
}
Common Errors
400 Bad Request
Invalid input or parameters:Copy
try {
const result = await raptor.process('document.pdf', {
chunkSize: 5000 // Too large (max 2048)
});
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 400) {
console.error('Invalid parameters:', error.message);
// Example: "chunk_size must be between 128 and 2048"
}
}
- Invalid chunk size (not in range 128-2048)
- Invalid chunk overlap (not in range 0-512)
- Invalid file type (not in allowed MIME types)
- Invalid UUID format
401 Unauthorized
Invalid or missing API key:Copy
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 401) {
console.error('Authentication failed');
console.error('Check your API key');
// Verify API key is set
console.log('API Key:', process.env.RAPTOR_API_KEY ? 'Set' : 'Missing');
}
}
- Verify API key is correct
- Check environment variable is loaded
- Ensure API key starts with
rd_live_orrd_test_
404 Not Found
Resource not found:Copy
try {
const document = await raptor.getDocument('invalid-id');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 404) {
console.error('Document not found');
// Handle missing document
}
}
- Invalid document ID
- Document was deleted
- Document belongs to different user
413 Request Entity Too Large
File too large:Copy
try {
const result = await raptor.process('huge-file.pdf');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 413) {
console.error('File too large');
console.error('Maximum file size: 100MB');
// Suggest splitting or compressing
suggestFileSplit();
}
}
429 Too Many Requests
Rate limit exceeded:Copy
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 429) {
console.error('Rate limit exceeded');
// Check rate limit headers
const retryAfter = error.response?.headers?.['retry-after'];
console.log(`Retry after: ${retryAfter} seconds`);
// Wait and retry
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return await raptor.process('document.pdf');
}
}
500 Internal Server Error
Server error:Copy
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 500) {
console.error('Server error');
console.error('Please try again later');
// Log for support
logErrorToSupport(error);
}
}
503 Service Unavailable
Service temporarily unavailable:Copy
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 503) {
console.error('Service unavailable');
// Retry with exponential backoff
await retryWithBackoff(() => raptor.process('document.pdf'));
}
}
Network Errors
Handle network failures:Copy
try {
const result = await raptor.process('document.pdf');
} catch (error) {
if (error instanceof RaptorError) {
if (error.message.includes('ECONNREFUSED')) {
console.error('Cannot connect to API');
console.error('Check your internet connection');
} else if (error.message.includes('ETIMEDOUT')) {
console.error('Request timed out');
console.error('Try increasing timeout:');
console.log('new Raptor({ timeout: 600000 })');
}
}
}
Timeout Errors
Handle processing timeouts:Copy
try {
const result = await raptor.process('large-document.pdf', {
pollTimeout: 300000 // 5 minutes
});
} catch (error) {
if (error instanceof RaptorError && error.message.includes('timeout')) {
console.error('Processing timeout');
// Option 1: Increase timeout
const result = await raptor.process('large-document.pdf', {
pollTimeout: 600000 // 10 minutes
});
// Option 2: Process async
const result = await raptor.process('large-document.pdf', {
wait: false // Don't wait for completion
});
// Poll manually
const variant = await raptor.getVariant(result.variantId);
console.log(`Status: ${variant.status}`);
}
}
Validation Errors
Handle file validation errors:Copy
async function uploadDocument(file: File) {
// Client-side validation
if (file.size > 100 * 1024 * 1024) {
throw new Error('File too large (max 100MB)');
}
const allowedTypes = ['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
if (!allowedTypes.includes(file.type)) {
throw new Error(`Invalid file type: ${file.type}`);
}
try {
const result = await raptor.process(file);
return result;
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 400) {
// Handle specific validation errors
if (error.message.includes('mime type')) {
throw new Error('File type not supported');
}
}
throw error;
}
}
Comprehensive Error Handler
Copy
import Raptor, { RaptorError, RaptorAPIError } from '@raptor-data/ts-sdk';
async function processDocumentSafely(filePath: string) {
try {
const result = await raptor.process(filePath);
return result;
} catch (error) {
if (error instanceof RaptorAPIError) {
// API errors
switch (error.statusCode) {
case 400:
console.error('Invalid request:', error.message);
break;
case 401:
console.error('Authentication failed. Check your API key.');
break;
case 404:
console.error('Resource not found');
break;
case 413:
console.error('File too large (max 100MB)');
break;
case 429:
console.error('Rate limit exceeded. Please wait and try again.');
const retryAfter = error.response?.headers?.['retry-after'] || 60;
console.log(`Retry after ${retryAfter} seconds`);
break;
case 500:
case 503:
console.error('Server error. Please try again later.');
break;
default:
console.error(`API Error ${error.statusCode}:`, error.message);
}
// Log full response for debugging
console.error('Full response:', error.response);
} else if (error instanceof RaptorError) {
// Client errors
console.error('Client error:', error.message);
if (error.message.includes('timeout')) {
console.error('Request timed out. Try increasing timeout.');
} else if (error.message.includes('ECONNREFUSED')) {
console.error('Cannot connect to API. Check your internet connection.');
}
} else {
// Unknown error
console.error('Unexpected error:', error);
}
// Re-throw or return null
throw error;
}
}
Retry Logic
Implement retry with exponential backoff:Copy
async function processWithRetry(
filePath: string,
maxRetries = 3,
baseDelay = 1000
) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await raptor.process(filePath);
} catch (error) {
const isLastAttempt = attempt === maxRetries - 1;
if (error instanceof RaptorAPIError) {
// Don't retry client errors (4xx)
if (error.statusCode >= 400 && error.statusCode < 500) {
throw error;
}
// Retry server errors (5xx) and rate limits
if (!isLastAttempt) {
const delay = baseDelay * Math.pow(2, attempt);
console.log(`Attempt ${attempt + 1} failed. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
}
// Re-throw on last attempt
throw error;
}
}
}
// Usage
try {
const result = await processWithRetry('document.pdf');
console.log('Success!');
} catch (error) {
console.error('All retries failed');
}
Error Recovery
Graceful Degradation
Copy
async function processDocument(file: File) {
try {
// Try with advanced features
return await raptor.process(file, {
calculateQualityScores: true,
tableContextGeneration: true,
processImages: true
});
} catch (error) {
if (error instanceof RaptorAPIError && error.statusCode === 500) {
console.warn('Advanced features failed, trying basic processing');
// Fall back to basic processing
return await raptor.process(file, {
calculateQualityScores: false,
tableContextGeneration: false,
processImages: false
});
}
throw error;
}
}
Cancel on Error
Copy
async function processWithCancel(file: File) {
try {
const result = await raptor.process(file, {
wait: false // Start async processing
});
// Monitor processing
const variant = await raptor.getVariant(result.variantId);
if (variant.status === 'failed') {
console.error('Processing failed:', variant.error);
// Cancel if needed
await raptor.cancelProcessing(result.variantId);
throw new Error('Processing failed');
}
return result;
} catch (error) {
console.error('Upload error:', error);
throw error;
}
}
Best Practices
Always catch errors: Wrap SDK calls in try-catch blocks to handle failures gracefully.
Don’t retry 4xx errors: Client errors (400-499) indicate invalid requests. Fix the issue instead of retrying.
Log errors for debugging: Log full error details (statusCode, message, response) to help troubleshoot issues.
Production Error Handling
Copy
import Raptor, { RaptorError, RaptorAPIError } from '@raptor-data/ts-sdk';
class DocumentProcessor {
private raptor: Raptor;
private logger: Logger;
constructor(apiKey: string, logger: Logger) {
this.raptor = new Raptor({ apiKey });
this.logger = logger;
}
async process(file: File): Promise<ProcessResult | null> {
try {
const result = await this.raptor.process(file, {
wait: true,
chunkSize: 512
});
this.logger.info('Document processed', {
documentId: result.documentId,
chunks: result.chunks.length
});
return result;
} catch (error) {
// Log error
this.logger.error('Document processing failed', {
filename: file.name,
error: error instanceof Error ? error.message : 'Unknown error'
});
// Handle specific errors
if (error instanceof RaptorAPIError) {
switch (error.statusCode) {
case 429:
// Rate limit - notify user
this.notifyRateLimit();
break;
case 401:
// Auth error - critical
this.alertAuthFailure();
break;
case 500:
case 503:
// Server error - retry later
await this.queueForRetry(file);
break;
}
}
// Return null instead of throwing
return null;
}
}
private notifyRateLimit() {
// Send notification to user
}
private alertAuthFailure() {
// Alert developers
}
private async queueForRetry(file: File) {
// Add to retry queue
}
}