AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Error Handler Generator

skill-girijashankarj-cursor-handbook-error-handler-generator · by girijashankarj

Generate typed error classes, error handling middleware, and HTTP error mapping following project conventions. Use when the user asks to set up error handling, create error classes, or implement error middleware.

No reviews yet
0 installs
33 views
0.0% view→install

Install

$ agentstack add skill-girijashankarj-cursor-handbook-error-handler-generator

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-girijashankarj-cursor-handbook-error-handler-generator)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Error Handler Generator? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: Error Handler Generator

Create a comprehensive error handling system with typed error classes, centralized middleware, and consistent API error responses.

Trigger

When the user asks to create error handling, set up error classes, implement error middleware, or standardize error responses.

Prerequisites

  • [ ] Framework identified (Express, Fastify, Koa, etc.)
  • [ ] Response envelope format known ({ error: { code, message }, meta })
  • [ ] Error categories for the domain identified

Steps

Step 1: Define Error Hierarchy

// errors/base.ts
export class AppError extends Error {
  public readonly statusCode: number;
  public readonly code: string;
  public readonly isOperational: boolean;
  public readonly details?: Record;

  constructor(params: {
    message: string;
    statusCode: number;
    code: string;
    isOperational?: boolean;
    details?: Record;
  }) {
    super(params.message);
    this.name = this.constructor.name;
    this.statusCode = params.statusCode;
    this.code = params.code;
    this.isOperational = params.isOperational ?? true;
    this.details = params.details;
    Error.captureStackTrace(this, this.constructor);
  }
}

Step 2: Create Specific Error Classes

// errors/index.ts
export class ValidationError extends AppError {
  constructor(message: string, details?: Record) {
    super({ message, statusCode: 400, code: 'VALIDATION_ERROR', details });
  }
}

export class AuthenticationError extends AppError {
  constructor(message = 'Authentication required') {
    super({ message, statusCode: 401, code: 'AUTHENTICATION_ERROR' });
  }
}

export class AuthorizationError extends AppError {
  constructor(message = 'Insufficient permissions') {
    super({ message, statusCode: 403, code: 'AUTHORIZATION_ERROR' });
  }
}

export class NotFoundError extends AppError {
  constructor(resource: string, id?: string) {
    const msg = id ? `${resource} with id '${id}' not found` : `${resource} not found`;
    super({ message: msg, statusCode: 404, code: 'NOT_FOUND' });
  }
}

export class ConflictError extends AppError {
  constructor(message: string) {
    super({ message, statusCode: 409, code: 'CONFLICT' });
  }
}

export class RateLimitError extends AppError {
  constructor(retryAfter?: number) {
    super({
      message: 'Rate limit exceeded',
      statusCode: 429,
      code: 'RATE_LIMIT_EXCEEDED',
      details: retryAfter ? { retryAfterSeconds: retryAfter } : undefined,
    });
  }
}

export class ExternalServiceError extends AppError {
  constructor(serviceName: string, message?: string) {
    super({
      message: message || `External service error: ${serviceName}`,
      statusCode: 502,
      code: 'EXTERNAL_SERVICE_ERROR',
      details: { service: serviceName },
    });
  }
}

export class InternalError extends AppError {
  constructor(message = 'An unexpected error occurred') {
    super({ message, statusCode: 500, code: 'INTERNAL_ERROR', isOperational: false });
  }
}

Step 3: Create Error Middleware

// middleware/error-handler.ts
import { Request, Response, NextFunction } from 'express';
import { AppError } from '../errors/base';
import { logger } from '../utils/logger';

export function errorHandler(
  err: Error,
  req: Request,
  res: Response,
  _next: NextFunction
): void {
  const correlationId = req.headers['x-correlation-id'] as string || 'unknown';

  if (err instanceof AppError) {
    logger.warn({
      correlationId,
      error: err.code,
      message: err.message,
      statusCode: err.statusCode,
      path: req.path,
      method: req.method,
    });

    res.status(err.statusCode).json({
      error: {
        code: err.code,
        message: err.message,
        ...(err.details && { details: err.details }),
      },
      meta: {
        correlationId,
        timestamp: new Date().toISOString(),
      },
    });
    return;
  }

  // Unexpected errors — don't expose details
  logger.error({
    correlationId,
    error: 'INTERNAL_ERROR',
    message: err.message,
    stack: err.stack,
    path: req.path,
    method: req.method,
  });

  res.status(500).json({
    error: {
      code: 'INTERNAL_ERROR',
      message: 'An unexpected error occurred',
    },
    meta: {
      correlationId,
      timestamp: new Date().toISOString(),
    },
  });
}

Step 4: Create Async Handler Wrapper

// middleware/async-handler.ts
import { Request, Response, NextFunction, RequestHandler } from 'express';

export const asyncHandler = (
  fn: (req: Request, res: Response, next: NextFunction) => Promise
): RequestHandler => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

Step 5: Add Error Mapping for External Errors

// errors/mappers.ts
import { AppError, ValidationError, InternalError } from './index';
import { ZodError } from 'zod';

export function mapToAppError(err: unknown): AppError {
  if (err instanceof AppError) return err;

  if (err instanceof ZodError) {
    return new ValidationError('Validation failed', {
      fields: err.errors.map(e => ({
        path: e.path.join('.'),
        message: e.message,
      })),
    });
  }

  if (err instanceof SyntaxError && 'body' in err) {
    return new ValidationError('Invalid JSON in request body');
  }

  return new InternalError();
}

Step 6: Wire Into Application

// app.ts
import { errorHandler } from './middleware/error-handler';

// ... routes ...

// Error handler must be LAST middleware
app.use(errorHandler);

Step 7: Add Tests

describe('Error handling', () => {
  it('should return 400 for validation errors', async () => {
    const res = await request(app).post('/api/v1/orders').send({});
    expect(res.status).toBe(400);
    expect(res.body.error.code).toBe('VALIDATION_ERROR');
    expect(res.body.meta.correlationId).toBeDefined();
  });

  it('should return 500 with safe message for unexpected errors', async () => {
    const res = await request(app).get('/api/v1/error-trigger');
    expect(res.status).toBe(500);
    expect(res.body.error.message).toBe('An unexpected error occurred');
    expect(res.body.error.code).toBe('INTERNAL_ERROR');
  });

  it('should not expose stack traces to clients', async () => {
    const res = await request(app).get('/api/v1/error-trigger');
    expect(res.body.error.stack).toBeUndefined();
  });
});

Rules

  • NEVER expose stack traces, internal paths, or implementation details to API consumers
  • NEVER log the full request/response body (may contain PII)
  • ALWAYS include correlationId in error responses and logs
  • ALWAYS distinguish operational errors (expected) from programmer errors (unexpected)
  • ALWAYS log unexpected errors at error level with full stack trace server-side
  • Use the AppError hierarchy — don't throw raw Error objects from business logic
  • Map third-party errors to AppError subclasses at the boundary

Completion

Complete error handling system with base class, specific error types, middleware, async wrapper, error mappers, and tests.

If a Step Fails

  • Framework not Express: Adapt middleware signature for Fastify/Koa/etc.
  • Zod not used: Replace Zod mapper with project's validation library
  • No logger: Use console.error as fallback, recommend structured logger
  • Existing error system: Extend rather than replace, maintain backward compatibility

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.