> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/wevm/incur/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error classes for structured error handling in CLI applications

The `Errors` module provides a hierarchy of error classes designed for CLI applications, with support for error chaining, structured field errors, and machine-readable error codes.

## Classes

### BaseError

Base error class with support for short messages, detail extraction from cause chains, and cause traversal.

<ParamField path="shortMessage" type="string" required>
  The short, human-readable error message (without details)
</ParamField>

<ParamField path="options" type="BaseError.Options">
  Configuration options for the error
</ParamField>

<ResponseField name="name" type="string">
  The error name: `'Incur.BaseError'`
</ResponseField>

<ResponseField name="shortMessage" type="string">
  The short, human-readable error message
</ResponseField>

<ResponseField name="details" type="string | undefined">
  Details extracted from the cause's message, if any
</ResponseField>

<ResponseField name="message" type="string">
  The full error message, combining shortMessage and details
</ResponseField>

#### Usage

```typescript theme={null}
import { BaseError } from 'incur'

const cause = new Error('Connection timed out after 30s')
const error = new BaseError('Failed to connect to database', { cause })

console.log(error.shortMessage)
// 'Failed to connect to database'

console.log(error.details)
// 'Connection timed out after 30s'

console.log(error.message)
// 'Failed to connect to database\n\nDetails: Connection timed out after 30s'
```

#### Method: walk

Traverses the cause chain. Without a callback, returns the deepest cause. With a callback, returns the first cause where the callback returns `true`.

<ParamField path="fn" type="(error: unknown) => boolean">
  Optional predicate function to find a specific error in the cause chain
</ParamField>

<ResponseField name="return" type="unknown">
  The deepest cause (no callback) or the first matching cause (with callback)
</ResponseField>

```typescript theme={null}
import { BaseError } from 'incur'

const rootCause = new Error('ECONNREFUSED')
const networkError = new Error('Network unreachable', { cause: rootCause })
const appError = new BaseError('Failed to fetch data', { cause: networkError })

// Get deepest cause
const deepest = appError.walk()
console.log(deepest) // Error: ECONNREFUSED

// Find specific error
const networkErr = appError.walk((err) => 
  err instanceof Error && err.message.includes('Network')
)
console.log(networkErr) // Error: Network unreachable
```

### IncurError

CLI-specific error with machine-readable error codes, actionable hints, and retry flags.

<ParamField path="options" type="IncurError.Options" required>
  Configuration options for the error
</ParamField>

<ResponseField name="name" type="string">
  The error name: `'Incur.IncurError'`
</ResponseField>

<ResponseField name="code" type="string">
  Machine-readable error code (e.g., `'NOT_AUTHENTICATED'`, `'RATE_LIMITED'`)
</ResponseField>

<ResponseField name="hint" type="string | undefined">
  Actionable hint for the user to resolve the error
</ResponseField>

<ResponseField name="retryable" type="boolean">
  Whether the operation can be retried. Defaults to `false`.
</ResponseField>

#### Usage

```typescript theme={null}
import { IncurError } from 'incur'

throw new IncurError({
  code: 'NOT_AUTHENTICATED',
  message: 'Authentication required to access this resource',
  hint: 'Run `mycli login` to authenticate',
  retryable: false
})
```

#### Usage: Retryable Errors

```typescript theme={null}
import { IncurError } from 'incur'

function fetchData() {
  throw new IncurError({
    code: 'RATE_LIMITED',
    message: 'API rate limit exceeded',
    hint: 'Wait 60 seconds before retrying',
    retryable: true
  })
}

try {
  fetchData()
} catch (err) {
  if (err instanceof IncurError && err.retryable) {
    console.log('Retrying in 60 seconds...')
    // Implement retry logic
  }
}
```

#### Usage: Error Codes

```typescript theme={null}
import { IncurError } from 'incur'

enum ErrorCode {
  NOT_FOUND = 'NOT_FOUND',
  PERMISSION_DENIED = 'PERMISSION_DENIED',
  INVALID_INPUT = 'INVALID_INPUT'
}

function handleError(err: IncurError) {
  switch (err.code) {
    case ErrorCode.NOT_FOUND:
      console.error('Resource not found:', err.message)
      break
    case ErrorCode.PERMISSION_DENIED:
      console.error('Access denied:', err.hint)
      break
    case ErrorCode.INVALID_INPUT:
      console.error('Invalid input:', err.message)
      break
  }
}
```

### ValidationError

Validation error with per-field error details, typically thrown by the parser when Zod validation fails.

<ParamField path="options" type="ValidationError.Options" required>
  Configuration options for the error
</ParamField>

<ResponseField name="name" type="string">
  The error name: `'Incur.ValidationError'`
</ResponseField>

<ResponseField name="fieldErrors" type="FieldError[]">
  Array of per-field validation errors
</ResponseField>

#### Usage

```typescript theme={null}
import { ValidationError } from 'incur'

throw new ValidationError({
  message: 'Validation failed',
  fieldErrors: [
    {
      path: 'email',
      expected: 'string (email format)',
      received: 'invalid-email',
      message: 'Invalid email address'
    },
    {
      path: 'age',
      expected: 'number',
      received: 'string',
      message: 'Expected number, received string'
    }
  ]
})
```

#### Usage: Display Field Errors

```typescript theme={null}
import { ValidationError } from 'incur'

try {
  // Some validation that throws ValidationError
} catch (err) {
  if (err instanceof ValidationError) {
    console.error('Validation failed:')
    for (const fieldError of err.fieldErrors) {
      console.error(`  ${fieldError.path}: ${fieldError.message}`)
      console.error(`    Expected: ${fieldError.expected}`)
      console.error(`    Received: ${fieldError.received}`)
    }
  }
}
```

### ParseError

Error thrown when argument parsing fails (unknown flags, missing values, invalid syntax).

<ParamField path="options" type="ParseError.Options" required>
  Configuration options for the error
</ParamField>

<ResponseField name="name" type="string">
  The error name: `'Incur.ParseError'`
</ResponseField>

#### Usage

```typescript theme={null}
import { ParseError } from 'incur'

throw new ParseError({
  message: 'Unknown flag: --invalid-flag'
})
```

#### Usage: Parse Error Handling

```typescript theme={null}
import { parse, ParseError } from 'incur'

try {
  const { args, options } = parse(process.argv.slice(2), {
    options: z.object({ verbose: z.boolean() })
  })
} catch (err) {
  if (err instanceof ParseError) {
    console.error('Error:', err.message)
    console.error('Run with --help for usage information')
    process.exit(1)
  }
  throw err
}
```

## Types

### FieldError

A field-level validation error detail.

<ResponseField name="path" type="string">
  The field path that failed validation (e.g., `'email'`, `'user.address.zip'`)
</ResponseField>

<ResponseField name="expected" type="string">
  The expected value or type (e.g., `'string'`, `'number'`, `'email format'`)
</ResponseField>

<ResponseField name="received" type="string">
  The value that was received
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable validation message
</ResponseField>

```typescript theme={null}
type FieldError = {
  path: string
  expected: string
  received: string
  message: string
}
```

### BaseError.Options

Options for constructing a `BaseError`.

<ResponseField name="cause" type="Error | undefined">
  The underlying cause of this error
</ResponseField>

### IncurError.Options

Options for constructing an `IncurError`.

<ResponseField name="code" type="string" required>
  Machine-readable error code
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="hint" type="string | undefined">
  Actionable hint for the user
</ResponseField>

<ResponseField name="retryable" type="boolean | undefined">
  Whether the operation can be retried. Defaults to `false`.
</ResponseField>

<ResponseField name="cause" type="Error | undefined">
  The underlying cause
</ResponseField>

### ValidationError.Options

Options for constructing a `ValidationError`.

<ResponseField name="message" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="fieldErrors" type="FieldError[] | undefined">
  Per-field validation errors
</ResponseField>

<ResponseField name="cause" type="Error | undefined">
  The underlying cause
</ResponseField>

### ParseError.Options

Options for constructing a `ParseError`.

<ResponseField name="message" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="cause" type="Error | undefined">
  The underlying cause
</ResponseField>

## Error Hierarchy

All error classes extend `BaseError`, which extends the native `Error` class:

```
Error (native)
  └─ BaseError
      ├─ IncurError
      ├─ ValidationError
      └─ ParseError
```

This allows you to catch errors at different levels of specificity:

```typescript theme={null}
import { BaseError, IncurError, ValidationError, ParseError } from 'incur'

try {
  // CLI operation
} catch (err) {
  if (err instanceof ValidationError) {
    // Handle validation errors specifically
  } else if (err instanceof ParseError) {
    // Handle parse errors
  } else if (err instanceof IncurError) {
    // Handle other CLI errors
  } else if (err instanceof BaseError) {
    // Handle any BaseError
  } else {
    // Handle unknown errors
  }
}
```
