Error Handling
Comprehensive error handling strategies and best practices for GPT Image 1 MCP, including error codes, retry logic, and recovery mechanisms.
Overview
GPT Image 1 MCP provides robust error handling with detailed error information, automatic recovery mechanisms, and comprehensive logging. This guide covers:
- Error Types: Understanding different error categories
- Error Codes: Complete reference of error codes and meanings
- Retry Logic: Implementing intelligent retry strategies
- Recovery Mechanisms: Handling failures gracefully
- Monitoring: Tracking and logging errors
Error Response Format
All errors follow a consistent format across all tools:
json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": {
"additional": "context-specific information",
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "req_123456789"
}
}
}
Error Categories
Authentication Errors
API_KEY_INVALID
- Description: OpenAI API key is invalid or expired
- HTTP Status: 401
- Retry: No (fix API key)
json
{
"success": false,
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid OpenAI API key",
"details": {
"key_format": "sk-...",
"suggestion": "Check your OpenAI API key format and permissions"
}
}
}
API_KEY_MISSING
- Description: No API key provided
- HTTP Status: 401
- Retry: No (provide API key)
json
{
"success": false,
"error": {
"code": "API_KEY_MISSING",
"message": "OpenAI API key is required",
"details": {
"env_var": "OPENAI_API_KEY",
"suggestion": "Set the OPENAI_API_KEY environment variable"
}
}
}
Rate Limiting Errors
RATE_LIMIT_EXCEEDED
- Description: API rate limit exceeded
- HTTP Status: 429
- Retry: Yes (with exponential backoff)
json
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded",
"details": {
"limit": "50 requests per minute",
"reset_time": "2024-01-15T10:31:00Z",
"retry_after": 60
}
}
}
QUOTA_EXCEEDED
- Description: API quota/credits exceeded
- HTTP Status: 429
- Retry: No (upgrade plan or add credits)
json
{
"success": false,
"error": {
"code": "QUOTA_EXCEEDED",
"message": "API quota exceeded",
"details": {
"current_usage": "100%",
"billing_period": "monthly",
"suggestion": "Upgrade your OpenAI plan or add credits"
}
}
}
Validation Errors
VALIDATION_ERROR
- Description: Input validation failed (e.g., non-English text detected)
- HTTP Status: 400
- Retry: No (fix input)
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Only English text is supported for optimal gpt-image-1 performance",
"details": {
"field": "prompt",
"detected_language": "japanese",
"suggestion": "Please translate your prompt to English using your LLM client first",
"example": "Use your LLM: 'Translate to English: 美しい桜の花'"
}
}
}
INVALID_PARAMS
- Description: Invalid parameters provided
- HTTP Status: 400
- Retry: No (fix parameters)
json
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "Invalid parameters provided",
"details": {
"invalid_fields": ["aspect_ratio", "quality"],
"aspect_ratio": "Must be one of: square, landscape, portrait",
"quality": "Must be one of: standard, hd"
}
}
}
PROMPT_TOO_LONG
- Description: Prompt exceeds maximum length
- HTTP Status: 400
- Retry: No (shorten prompt)
json
{
"success": false,
"error": {
"code": "PROMPT_TOO_LONG",
"message": "Prompt exceeds maximum length",
"details": {
"current_length": 1500,
"max_length": 1000,
"suggestion": "Reduce prompt length or split into multiple requests"
}
}
}
Content Policy Errors
CONTENT_POLICY_VIOLATION
- Description: Content violates OpenAI's usage policies
- HTTP Status: 400
- Retry: No (modify content)
json
{
"success": false,
"error": {
"code": "CONTENT_POLICY_VIOLATION",
"message": "Content violates usage policies",
"details": {
"violation_type": "inappropriate_content",
"flagged_content": "specific problematic text",
"suggestion": "Revise the prompt to comply with usage policies"
}
}
}
Network and Service Errors
SERVICE_UNAVAILABLE
- Description: OpenAI service is temporarily unavailable
- HTTP Status: 503
- Retry: Yes (with backoff)
json
{
"success": false,
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "OpenAI service is temporarily unavailable",
"details": {
"service": "OpenAI gpt-image-1",
"retry_after": 300,
"suggestion": "Try again in a few minutes"
}
}
}
TIMEOUT
- Description: Request timed out
- HTTP Status: 408
- Retry: Yes (with increased timeout)
json
{
"success": false,
"error": {
"code": "TIMEOUT",
"message": "Request timed out",
"details": {
"timeout_duration": 60,
"suggestion": "Try again or increase timeout setting"
}
}
}
Tool-Specific Errors
IMAGE_GENERATION_FAILED
- Description: Image generation failed
- HTTP Status: 500
- Retry: Yes (limited retries)
json
{
"success": false,
"error": {
"code": "IMAGE_GENERATION_FAILED",
"message": "Failed to generate image",
"details": {
"prompt": "user's prompt",
"error_type": "generation_error",
"suggestion": "Try simplifying the prompt or adjusting parameters"
}
}
}
INVALID_IMAGE_URL
- Description: Invalid or inaccessible image URL
- HTTP Status: 400
- Retry: No (fix URL)
json
{
"success": false,
"error": {
"code": "INVALID_IMAGE_URL",
"message": "Invalid or inaccessible image URL",
"details": {
"url": "https://example.com/image.jpg",
"status_code": 404,
"suggestion": "Ensure the URL is publicly accessible"
}
}
}
Retry Strategies
Exponential Backoff
typescript
async function retryWithBackoff<T>(
fn: () => Promise<T>,
maxRetries: number = 3,
baseDelay: number = 1000,
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
if (shouldRetry(error)) {
const delay = baseDelay * Math.pow(2, attempt);
await new Promise((resolve) => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
throw new Error("Max retries exceeded");
}
function shouldRetry(error: any): boolean {
const retryableCodes = [
"RATE_LIMIT_EXCEEDED",
"SERVICE_UNAVAILABLE",
"TIMEOUT",
"NETWORK_ERROR",
];
return retryableCodes.includes(error.code);
}
Rate Limit Handling
typescript
async function handleRateLimit(error: any) {
if (error.code === "RATE_LIMIT_EXCEEDED") {
const retryAfter = error.details.retry_after || 60;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
return true; // Indicate retry is possible
}
return false;
}
Smart Retry Logic
typescript
async function smartRetry<T>(
operation: () => Promise<T>,
options: {
maxRetries?: number;
baseDelay?: number;
maxDelay?: number;
retryCondition?: (error: any) => boolean;
} = {},
): Promise<T> {
const {
maxRetries = 3,
baseDelay = 1000,
maxDelay = 30000,
retryCondition = shouldRetry,
} = options;
let lastError: any;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (attempt === maxRetries || !retryCondition(error)) {
throw error;
}
// Handle rate limiting specially
if (error.code === "RATE_LIMIT_EXCEEDED") {
const retryAfter = error.details.retry_after || 60;
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
continue;
}
// Exponential backoff for other retryable errors
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw lastError;
}
Error Handling Patterns
Graceful Degradation
typescript
async function generateImageWithFallback(prompt: string) {
try {
// Try high quality first
return await client.callTool("generate-image", {
prompt,
quality: "hd",
style: "vivid",
});
} catch (error) {
if (error.code === "RATE_LIMIT_EXCEEDED") {
// Fallback to standard quality
console.log("HD rate limited, falling back to standard quality");
return await client.callTool("generate-image", {
prompt,
quality: "standard",
style: "natural",
});
}
throw error;
}
}
Circuit Breaker Pattern
typescript
class CircuitBreaker {
private failures = 0;
private lastFailureTime = 0;
private state: "closed" | "open" | "half-open" = "closed";
constructor(
private threshold: number = 5,
private timeout: number = 60000,
) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === "open") {
if (Date.now() - this.lastFailureTime > this.timeout) {
this.state = "half-open";
} else {
throw new Error("Circuit breaker is open");
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess() {
this.failures = 0;
this.state = "closed";
}
private onFailure() {
this.failures++;
this.lastFailureTime = Date.now();
if (this.failures >= this.threshold) {
this.state = "open";
}
}
}
Comprehensive Error Handler
typescript
class ErrorHandler {
private static logError(error: any, context: string) {
console.error(`[${context}] Error:`, {
code: error.code,
message: error.message,
details: error.details,
timestamp: new Date().toISOString(),
});
}
static async handle<T>(
operation: () => Promise<T>,
context: string,
options: {
retry?: boolean;
fallback?: () => Promise<T>;
notify?: (error: any) => void;
} = {},
): Promise<T> {
try {
if (options.retry) {
return await smartRetry(operation);
} else {
return await operation();
}
} catch (error) {
this.logError(error, context);
if (options.notify) {
options.notify(error);
}
if (options.fallback) {
console.log(`[${context}] Attempting fallback...`);
try {
return await options.fallback();
} catch (fallbackError) {
this.logError(fallbackError, `${context}-fallback`);
throw fallbackError;
}
}
throw error;
}
}
}
Usage Examples
Basic Error Handling
typescript
async function generateImage(prompt: string) {
try {
const result = await client.callTool("generate-image", {
prompt,
quality: "hd",
});
return result.data;
} catch (error) {
console.error("Image generation failed:", error.message);
switch (error.code) {
case "VALIDATION_ERROR":
throw new Error(
"Please translate your prompt to English using your LLM first.",
);
case "RATE_LIMIT_EXCEEDED":
throw new Error("Rate limit exceeded. Please try again later.");
case "CONTENT_POLICY_VIOLATION":
throw new Error(
"Content violates policies. Please revise your prompt.",
);
case "QUOTA_EXCEEDED":
throw new Error("API quota exceeded. Please upgrade your plan.");
default:
throw new Error("Image generation failed. Please try again.");
}
}
}
Advanced Error Handling
typescript
async function robustImageGeneration(prompt: string) {
return await ErrorHandler.handle(
() => client.callTool("generate-image", { prompt, quality: "hd" }),
"image-generation",
{
retry: true,
fallback: () =>
client.callTool("generate-image", {
prompt,
quality: "standard",
}),
notify: (error) => {
if (error.code === "QUOTA_EXCEEDED") {
// Send notification to admin
console.log("ALERT: API quota exceeded");
}
},
},
);
}
Batch Processing with Error Handling
typescript
async function processBatch(prompts: string[]) {
const results = [];
const errors = [];
for (const [index, prompt] of prompts.entries()) {
try {
const result = await smartRetry(() =>
client.callTool("generate-image", { prompt }),
);
results.push({
index,
prompt,
success: true,
data: result.data,
});
} catch (error) {
errors.push({
index,
prompt,
success: false,
error: {
code: error.code,
message: error.message,
},
});
}
}
return { results, errors };
}
Monitoring and Logging
Error Metrics
typescript
class ErrorMetrics {
private static metrics = new Map<string, number>();
static increment(errorCode: string) {
const current = this.metrics.get(errorCode) || 0;
this.metrics.set(errorCode, current + 1);
}
static getMetrics() {
return Object.fromEntries(this.metrics);
}
static reset() {
this.metrics.clear();
}
}
// Usage
try {
await client.callTool("generate-image", { prompt });
} catch (error) {
ErrorMetrics.increment(error.code);
throw error;
}
Health Monitoring
typescript
async function healthCheck() {
const tests = [
{ name: "API Key", test: () => testApiKey() },
{ name: "Image Generation", test: () => testImageGeneration() },
{ name: "Image Editing", test: () => testImageEditing() },
];
const results = await Promise.allSettled(
tests.map(async ({ name, test }) => {
try {
await test();
return { name, status: "healthy" };
} catch (error) {
return { name, status: "unhealthy", error: error.message };
}
}),
);
return results.map((result) =>
result.status === "fulfilled" ? result.value : result.reason,
);
}
Best Practices
Error Prevention
- Validate Input: Check parameters before API calls
- Set Timeouts: Configure appropriate timeouts
- Rate Limiting: Implement client-side rate limiting
- Content Filtering: Pre-filter content for policy violations
Error Recovery
- Retry Logic: Implement intelligent retry mechanisms
- Fallbacks: Provide alternative approaches
- Graceful Degradation: Reduce quality/features when needed
- Circuit Breakers: Prevent cascading failures
Error Reporting
- Structured Logging: Use consistent log formats
- Error Tracking: Monitor error patterns
- Alerting: Set up alerts for critical errors
- User Feedback: Provide clear error messages to users
Configuration
Environment Variables
bash
# Error handling configuration
ERROR_RETRY_ATTEMPTS=3
ERROR_RETRY_DELAY=1000
ERROR_CIRCUIT_BREAKER_THRESHOLD=5
ERROR_CIRCUIT_BREAKER_TIMEOUT=60000
ERROR_LOG_LEVEL=error
MCP Configuration
json
{
"mcpServers": {
"@napolab/gpt-image-1-mcp": {
"env": {
"ERROR_RETRY_ATTEMPTS": "3",
"ERROR_RETRY_DELAY": "1000",
"ERROR_LOG_LEVEL": "error"
}
}
}
}
Next Steps
- Rate Limiting - Detailed rate limiting strategies
- API Overview - Complete API reference
- Environment Variables - Configuration options
- Examples - Practical implementation examples