AI Tools Compared

Generate production-ready error handling by explicitly requesting typed errors, specific exception cases, logging statements, and retry logic in prompts. This guide shows exactly which error-handling patterns to request in prompts that consistently produce strong, maintainable error handling.

Error handling remains one of the most critical yet frequently neglected aspects of production software. When you delegate code generation to AI tools, getting strong error handling requires specific prompting strategies. This guide shows you how to craft prompts that produce production-ready error handling code across multiple programming languages and frameworks.

The Problem with Generic Error Handling Prompts

Most developers ask AI tools for error handling using vague requests like “add error handling” or “handle exceptions properly.” These prompts produce generic try-catch blocks that catch Exception without distinguishing between recoverable errors, programming bugs, and system failures.

Production-grade error handling demands specificity. Your prompts must communicate the error categories your application encounters, the recovery strategies appropriate for each, logging requirements, and whether errors should propagate or be contained.

Prompt Structure for Production Error Handling

Effective error handling prompts contain five distinct components:

  1. Error taxonomy: Define categories of errors (validation, network, authentication, database, etc.)

  2. Recovery actions: Specify what happens after each error type

  3. Logging requirements: Indicate log levels, contextual data, and retention needs

  4. API contract: Define how errors reach callers (status codes, error bodies)

  5. Environment context: Specify production constraints like timeouts and retries

A well-structured prompt includes all five elements:

Generate Python error handling for a FastAPI endpoint that calls an external payment API.
Handle three error categories:
1) Validation errors (return 422 with field-specific messages),
2) Payment gateway timeouts (retry twice, then return 503),
3) Authentication failures (log attempt, return 401).
Include structured logging with request IDs, and use custom exception classes.

Language-Specific Prompt Optimization

Python FastAPI Applications

For Python, specify exception class hierarchies and FastAPI’s HTTPException usage. Include Pydantic validation requirements in your prompt:

Create custom exception classes for a data processing pipeline:
DataValidationError (422), ProcessingTimeoutError (504), StorageQuotaError (507).
Each should accept a message, error code, and metadata dict.
Implement a dependency that catches these and returns proper JSON responses
with the error code at $.error.code and message at $.error.message.

This produces cleaner error handling than generic try-catch approaches:

class DataValidationError(Exception):
    def __init__(self, message: str, error_code: str, metadata: dict = None):
        super().__init__(message)
        self.message = message
        self.error_code = error_code
        self.metadata = metadata or {}

class ErrorHandler:
    @staticmethod
    def handle_validation_error(exc: DataValidationError) -> JSONResponse:
        return JSONResponse(
            status_code=422,
            content={
                "error": {
                    "code": exc.error_code,
                    "message": exc.message,
                    "details": exc.metadata
                }
            }
        )

JavaScript/TypeScript Node.js Applications

For TypeScript, emphasize type-safe error handling and proper typing for error objects:

Generate TypeScript error handling for a REST endpoint that processes file uploads.
Create:
1) An AppError base class with status code, message, and isOperational flag
2) Specific subclasses: ValidationError, StorageError, ProcessingError
3) Express error middleware that logs operational vs programming errors differently
4) A wrapper function that types try-catch results as Promise<T | Error>

The resulting code includes proper typing:

class AppError extends Error {
  constructor(
    public statusCode: number,
    public message: string,
    public isOperational: boolean = true
  ) {
    super(message);
    Object.setPrototypeOf(this, AppError.prototype);
  }
}

class ValidationError extends AppError {
  constructor(message: string, public field?: string) {
    super(400, message, true);
    this.field = field;
  }
}

const errorMiddleware = (
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
): void => {
  if (err instanceof AppError) {
    logger.warn({
      message: err.message,
      statusCode: err.statusCode,
      ...(err instanceof ValidationError && { field: err.field })
    });
    res.status(err.statusCode).json({ error: err.message });
    return;
  }
  logger.error({ err, stack: err.stack });
  res.status(500).json({ error: "Internal server error" });
};

Java Spring Boot Applications

For Spring Boot, specify exception handler annotations and proper HTTP status mapping:

Create a global exception handler using @ControllerAdvice for a Spring Boot REST API.
Handle: MethodArgumentNotValidException (400), EntityNotFoundException (404),
DatabaseConnectionException (503), and generic exceptions (500).
Include request tracking with MDC logging, and return RFC 7807 Problem Details.

Advanced Prompt Techniques

Retry and Circuit Breaker Patterns

Production systems require more than basic error catching. Include retry logic and circuit breaker patterns in your prompts:

Add circuit breaker logic to a Python function that calls a third-party API.
Configure: 5 failure threshold, 30-second recovery timeout, half-open state testing.
On circuit open, raise CircuitBreakerOpenError with retry-after header.
On retry, use exponential backoff with jitter (base: 1s, max: 30s).

Asynchronous Error Handling

For async code, specify how errors propagate through event loops:

Generate async error handling for a Node.js function that processes multiple
concurrent API calls using Promise.allSettled.
Collect all failures, log partial successes, and return a result object
with { successful: [...], failed: [...], partial: boolean }.

Error Recovery Strategies

Production error handling often includes recovery attempts:

Create a TypeScript function that attempts file processing with three strategies:
1) Primary: Read from primary storage
2) Fallback: Read from backup storage if primary fails
3) Emergency: Generate default data if both storages fail
Log each strategy attempt with timing, and include metrics for strategy effectiveness.

Testing Your Error Handling Prompts

Validate AI-generated error handling by prompting for test cases:

Generate Jest test cases for the error handling code above:
1) Test that ValidationError returns 400 with correct field in response
2) Test that network failures trigger retry (verify 3 attempts logged)
3) Test that unknown errors return 500 without leaking stack traces in production
4) Test that error responses include request ID for correlation

Common Prompt Failures and Fixes

Problem: AI generates catch(Exception e) that hides bugs

Fix: Explicitly ask for specific exception types and re-throw unknown ones

Problem: Errors lose context when propagating across layers

Fix: Request error enrichment at each layer with additional context

Problem: Missing logging makes debugging impossible

Fix: Specify log structure including timestamps, request IDs, and error hierarchies

Problem: Inconsistent error formats across endpoints

Fix: Request an unified error response schema and global error handler

Built by theluckystrike — More at zovo.one