Error Handling
Proper error handling with specific error classes
The SDK provides specific error classes for different failure scenarios, making it easy to handle errors appropriately in your application.
Error Classes
AuthenticationError
Thrown when API authentication fails (HTTP 401).
Common causes: Invalid API key, expired key, or missing key
NotFoundError
Thrown when a requested resource doesn't exist (HTTP 404).
Common causes: Invalid ID, deleted resource, or wrong endpoint
ValidationError
Thrown when request validation fails (HTTP 400).
Common causes: Missing required fields, invalid data types, or schema violations
RateLimitError
Thrown when rate limits are exceeded (HTTP 429).
Common causes: Too many requests in a short time period
GraphQLError
Thrown when GraphQL returns errors.
Common causes: Query syntax errors, resolver failures, or permission issues
NetworkError
Thrown when network requests fail.
Common causes: No internet connection, DNS failures, or timeouts
Import Error Classes
import Prompt Forge, {
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
GraphQLError,
NetworkError,
Prompt ForgeError // Base class for all SDK errors
} from '@promptforge/sdk'Basic Error Handling
import Prompt Forge, { AuthenticationError, NotFoundError } from '@promptforge/sdk'
const client = new Prompt Forge({
apiKey: process.env.PROMPTFORGE_API_KEY
})
try {
const result = await client.prompts.execute('prompt-id', {
topic: 'JavaScript'
})
console.log(result.output)
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed - check your API key')
// Maybe refresh the key or prompt user to login
} else if (error instanceof NotFoundError) {
console.error('Prompt not found - check the ID')
// Maybe show list of available prompts
} else {
console.error('Unexpected error:', error.message)
// Generic error handling
}
}Comprehensive Error Handling
import Prompt Forge, {
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
GraphQLError,
NetworkError
} from '@promptforge/sdk'
async function executePromptSafely(promptId, input) {
try {
const result = await client.prompts.execute(promptId, input)
return { success: true, data: result }
} catch (error) {
// Authentication errors
if (error instanceof AuthenticationError) {
console.error('Authentication failed')
console.error('Check that your API key is valid and not expired')
return {
success: false,
error: 'authentication_failed',
message: 'Please check your API credentials',
retry: false
}
}
// Not found errors
if (error instanceof NotFoundError) {
console.error('Resource not found')
return {
success: false,
error: 'not_found',
message: 'The requested prompt does not exist',
retry: false
}
}
// Validation errors
if (error instanceof ValidationError) {
console.error('Validation failed')
console.error('Errors:', error.errors)
return {
success: false,
error: 'validation_failed',
message: 'Input validation failed',
details: error.errors,
retry: false
}
}
// Rate limit errors
if (error instanceof RateLimitError) {
console.error('Rate limit exceeded')
console.error('Too many requests - please slow down')
return {
success: false,
error: 'rate_limit',
message: 'Please wait before trying again',
retry: true,
retryAfter: 60 // seconds
}
}
// GraphQL errors
if (error instanceof GraphQLError) {
console.error('GraphQL error')
console.error('Errors:', error.errors)
return {
success: false,
error: 'graphql_error',
message: error.message,
details: error.errors,
retry: false
}
}
// Network errors
if (error instanceof NetworkError) {
console.error('Network error')
console.error('Check your internet connection')
return {
success: false,
error: 'network_error',
message: 'Network request failed',
retry: true,
retryAfter: 5
}
}
// Unknown errors
console.error('Unknown error:', error)
return {
success: false,
error: 'unknown',
message: error.message || 'An unexpected error occurred',
retry: false
}
}
}
// Usage
const result = await executePromptSafely('prompt-id', {
topic: 'AI Ethics'
})
if (result.success) {
console.log(result.data.output)
} else {
console.error(`Error: ${result.message}`)
if (result.retry) {
console.log(`Retrying in ${result.retryAfter} seconds...`)
}
}Retry Logic
Implement automatic retries for transient failures like network errors or rate limits.
import { NetworkError, RateLimitError } from '@promptforge/sdk'
async function executeWithRetry(fn, maxRetries = 3) {
let lastError
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await fn()
} catch (error) {
lastError = error
// Only retry network errors and rate limits
const shouldRetry =
error instanceof NetworkError ||
error instanceof RateLimitError
if (!shouldRetry || attempt === maxRetries) {
throw error
}
// Exponential backoff
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`)
await new Promise(resolve => setTimeout(resolve, delay))
}
}
throw lastError
}
// Usage
try {
const result = await executeWithRetry(async () => {
return await client.prompts.execute('prompt-id', {
topic: 'Resilient Systems'
})
})
console.log(result.output)
} catch (error) {
console.error('Failed after retries:', error.message)
}Validation Error Details
ValidationError includes detailed information about what went wrong.
try {
await client.prompts.create({
name: '', // Invalid: empty string
template: 'Hello {{name}}',
// Missing required fields
})
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:')
error.errors.forEach(err => {
console.error(` - ${err.field}: ${err.message}`)
})
// Example output:
// - name: Name is required
// - provider: Provider is required
// - model: Model is required
}
}Error Logging
Log errors properly for debugging and monitoring.
import { Prompt ForgeError } from '@promptforge/sdk'
function logError(error, context = {}) {
const errorInfo = {
timestamp: new Date().toISOString(),
message: error.message,
type: error.name,
...context
}
// Add SDK-specific info
if (error instanceof Prompt ForgeError) {
errorInfo.statusCode = error.statusCode
if (error.errors) {
errorInfo.details = error.errors
}
}
// Log to your monitoring system
console.error(JSON.stringify(errorInfo, null, 2))
// Send to error tracking service
// Sentry.captureException(error, { extra: errorInfo })
// Datadog.logger.error(error.message, errorInfo)
}
try {
const result = await client.prompts.execute('prompt-id', input)
} catch (error) {
logError(error, {
operation: 'execute_prompt',
promptId: 'prompt-id',
userId: 'user-123'
})
}Best Practices
Always Use Try-Catch
All SDK methods that make API calls can throw errors. Always wrap them in try-catch blocks.
Handle Specific Errors
Don't just catch all errors generically. Handle specific error types differently based on whether they're user errors, transient failures, or system errors.
Implement Retries
Retry transient failures like network errors and rate limits with exponential backoff. Don't retry validation or authentication errors.
Log Everything
Log errors with context (operation, input, user ID) to make debugging easier. Use structured logging for better searchability.
User-Friendly Messages
Show user-friendly error messages to end users, but log technical details for debugging.
Complete Example
import Prompt Forge, {
AuthenticationError,
ValidationError,
RateLimitError,
NetworkError
} from '@promptforge/sdk'
const client = new Prompt Forge({
apiKey: process.env.PROMPTFORGE_API_KEY
})
async function generateContent(promptId, input) {
const maxRetries = 3
let attempt = 0
while (attempt < maxRetries) {
try {
attempt++
const result = await client.prompts.execute(promptId, input)
// Success!
return {
success: true,
output: result.output,
metrics: {
latency: result.latencyMs,
cost: result.costUsd,
tokens: {
in: result.tokenIn,
out: result.tokenOut
}
}
}
} catch (error) {
// Don't retry these errors
if (error instanceof AuthenticationError) {
return {
success: false,
error: 'auth_failed',
userMessage: 'Authentication failed. Please contact support.',
retry: false
}
}
if (error instanceof ValidationError) {
return {
success: false,
error: 'invalid_input',
userMessage: 'Please check your input and try again.',
details: error.errors,
retry: false
}
}
// Retry these errors
const shouldRetry =
(error instanceof NetworkError || error instanceof RateLimitError) &&
attempt < maxRetries
if (!shouldRetry) {
return {
success: false,
error: error.name,
userMessage: 'An error occurred. Please try again later.',
technicalMessage: error.message,
retry: false
}
}
// Wait before retrying
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
console.log(`Retry ${attempt}/${maxRetries} in ${delay}ms`)
await new Promise(resolve => setTimeout(resolve, delay))
}
}
}
// Usage
const result = await generateContent('prompt-id', {
topic: 'Error Handling Best Practices'
})
if (result.success) {
console.log(result.output)
console.log(`Cost: $${result.metrics.cost}`)
} else {
console.error(`Error: ${result.userMessage}`)
if (result.details) {
console.error('Details:', result.details)
}
}