# Aidd Error Causes

> Use the error-causes library for structured error handling in JavaScript/TypeScript. Use when throwing errors, catching errors, defining error types, or implementing error routing.

- Skill: `paralleldrive/aidd-error-causes` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add paralleldrive/aidd-error-causes`
- Raw SKILL.md: https://api.skillmd.com/api/skills/paralleldrive/aidd-error-causes/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: paralleldrive (https://skillmd.com/u/paralleldrive)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/paralleldrive/aidd-error-causes

---


# Error Causes Rule

Use the `error-causes` library for all error handling in JavaScript/TypeScript code to enable structured error handling with named causes.

## Why Error Causes?

- Enables structured error handling with named causes instead of relying on `instanceof` checks
- Works across memory realms (e.g., iframes) unlike `instanceof`
- Provides consistent error metadata (name, code, message, cause)
- Makes error handling explicit and self-documenting
- Allows for automatic error routing based on error names

## Import Statement

```js
import { createError } from "error-causes";
```

## Basic Usage

Instead of throwing plain errors:

```js
// ❌ DON'T
throw new Error('Config key "API_KEY" is required');
```

Use `createError` with structured metadata:

```js
// ✅ DO
throw createError({
  name: 'ConfigurationError',
  message: 'Required configuration key "API_KEY" is not defined',
  code: 'MISSING_CONFIG_KEY',
  requestedKey: 'API_KEY'
});
```

## Error Properties

Always include these properties in `createError`:

- `name` - Error name for matching (e.g., 'ValidationError', 'AuthenticationError')
- `message` - Human-readable error message
- `code` (optional) - Error code for programmatic handling
- Custom properties (optional) - Any additional context relevant to the error

## Wrapping Caught Errors

When catching and re-throwing errors, preserve the original error as `cause`:

```js
try {
  await someOperation();
} catch (originalError) {
  throw createError({
    name: 'OperationError',
    message: 'Failed to perform operation',
    code: 'OPERATION_FAILED',
    cause: originalError  // Preserve original error
  });
}
```

## Factory Validation Errors

For factory functions that validate parameters at creation time:

```js
const createMiddleware = ({ requiredParam } = {}) => {
  if (!requiredParam) {
    throw createError({
      name: 'ValidationError',
      message: 'requiredParam is required',
      code: 'MISSING_REQUIRED_PARAM'
    });
  }

  return async ({ request, response }) => {
    // middleware implementation
  };
};
```

## Testing Error Causes

In tests, verify the error's `cause` property:

```js
let error;
try {
  functionThatThrows();
} catch (e) {
  error = e;
}

assert({
  given: 'invalid input',
  should: 'throw Error with cause',
  actual: error instanceof Error && error.cause !== undefined,
  expected: true
});

assert({
  given: 'invalid input',
  should: 'have correct error name',
  actual: error.cause.name,
  expected: 'ValidationError'
});

assert({
  given: 'invalid input',
  should: 'have correct error code',
  actual: error.cause.code,
  expected: 'MISSING_REQUIRED_PARAM'
});
```

## Error Handler Pattern

For APIs that define multiple error types, use the `errorCauses` pattern:

```js
import { errorCauses, createError } from "error-causes";

// Define all possible errors for your API
const [apiErrors, handleApiErrors] = errorCauses({
  NotFound: {
    code: 404,
    message: 'Resource not found'
  },
  ValidationError: {
    code: 400,
    message: 'Invalid input'
  },
  Unauthorized: {
    code: 401,
    message: 'Authentication required'
  }
});

const { NotFound, ValidationError, Unauthorized } = apiErrors;

// Throw errors
if (!resource) throw createError(NotFound);

// Handle errors with automatic routing
someAsyncCall()
  .catch(handleApiErrors({
    NotFound: ({ message }) => console.log(message),
    ValidationError: ({ message }) => console.log(message),
    Unauthorized: ({ message }) => redirect('/login')
  }));
```

## Rules

1. **Always use `createError`** instead of `new Error()` for thrown errors
2. **Always include `name` and `message`** in error metadata
3. **Include `code`** when the error needs programmatic handling
4. **Preserve original errors** using the `cause` property when re-throwing
5. **Add context** with custom properties relevant to the error
6. **Test the `cause` property** in error tests, not just the error message
7. **Define error types** using `errorCauses()` for APIs with multiple error types

