stacks-error-handling

$npx mdskill add stacksjs/stacks/stacks-error-handling

Handle errors in Stacks with Result types, error pages, and logging.

  • Implement type-safe error handling using Ok/Err Result types.
  • Depends on @stacksjs/error-handling and config/errors.ts.
  • Decides based on environment: dev shows stack traces, production shows friendly pages.
  • Delivers via handleError function, ErrorHandler class, and log file writing.

SKILL.md

.github/skills/stacks-error-handlingView on GitHub ↗
---
name: stacks-error-handling
description: Use when implementing error handling in Stacks — the Result type (Ok/Err), handleError function, error page rendering (development with stack traces, production with friendly messages), ErrorHandler class, ModelNotFoundException, HTTP error mapping, log file writing, or error configuration. Covers @stacksjs/error-handling and config/errors.ts.
license: MIT
compatibility: Bun >= 1.3.0, TypeScript
allowed-tools: Read Edit Write Bash Grep Glob
---

# Stacks Error Handling

Type-safe error handling with Result types, error pages, and structured logging.

## Key Paths
- Core package: `storage/framework/core/error-handling/src/`
- Configuration: `config/errors.ts`
- Error model: `storage/framework/models/Error.ts`

## Result Type (from ts-error-handling)

```typescript
import { ok, err, fromPromise } from '@stacksjs/error-handling'
import type { Result, Ok, Err, ResultAsync } from '@stacksjs/error-handling'

// Create results
const success: Ok<string> = ok('data')
const failure: Err<Error> = err(new Error('failed'))

// From promises
const result: ResultAsync<Data, Error> = fromPromise(fetchData())

// Pattern matching
if (result.isOk()) {
  console.log(result.value)
} else {
  console.error(result.error)
}
```

## Error Handler

```typescript
import { handleError, ErrorHandler } from '@stacksjs/error-handling'

// Function-based
handleError(error)
handleError(error, { shouldExit: true })

// Class-based
ErrorHandler.handle(error)
ErrorHandler.handleError(error, { shouldExit: true })
ErrorHandler.writeErrorToFile(error)
ErrorHandler.writeErrorToConsole(error)
```

## Log File Writing

```typescript
import { writeToLogFile, setLogPath } from '@stacksjs/error-handling'

setLogPath('/custom/log/path')
await writeToLogFile('Error message', { path: '/custom/path' })
```

Default log path: `storage/logs/stacks.log`

## Error Page Rendering

```typescript
import { ErrorPageHandler, renderError, renderErrorPage, renderProductionErrorPage, createErrorHandler, errorResponse } from '@stacksjs/error-handling'

// Development: shows stack trace, source code, file paths
const devPage = renderErrorPage(error, request)

// Production: friendly error message, no internals
const prodPage = renderProductionErrorPage(error, request)

// Auto-detect environment
const page = renderError(error, request)

// Create handler for routes
const handler = createErrorHandler()
const response = errorResponse(error, request)
```

## HTTP Error Mapping

```typescript
import { HTTP_ERRORS } from '@stacksjs/error-handling'

// Maps status codes to error details
HTTP_ERRORS[400]  // { title: 'Bad Request', ... }
HTTP_ERRORS[401]  // { title: 'Unauthorized', ... }
HTTP_ERRORS[403]  // { title: 'Forbidden', ... }
HTTP_ERRORS[404]  // { title: 'Not Found', ... }
HTTP_ERRORS[500]  // { title: 'Internal Server Error', ... }
```

## Custom Exceptions

```typescript
import { ModelNotFoundException } from '@stacksjs/error-handling'

throw new ModelNotFoundException('User not found')
```

## Error Page Types

```typescript
interface HttpError { status: number, title: string, message: string }
interface StackFrame { file: string, line: number, column: number, function?: string }
interface CodeSnippet { line: number, code: string, isHighlighted: boolean }
```

## Error Model (storage/framework/models/Error.ts)

Fields: type, message, stack (stacktrace), status, additional_info
Seeder: 10 records for testing

## config/errors.ts

Contains comprehensive validation error messages for all field types:
- String validation: required, minLength, maxLength, email, url, uuid, etc.
- Number validation: required, min, max, positive, negative, integer, etc.
- Enum validation: invalid value messages
- Date validation: format, before, after, etc.
- File validation: size, type, dimensions, etc.

## Gotchas
- Use `Result<T, E>` types instead of try/catch for recoverable errors
- `ok()` and `err()` are from `ts-error-handling` (neverthrow-compatible)
- Error pages automatically detect environment (dev shows stack traces, prod doesn't)
- `handleError()` logs to both console and file
- `ModelNotFoundException` is thrown by `findOrFail()` and `firstOrFail()` ORM methods
- The Error model persists errors to the database for tracking
- `config/errors.ts` is a comprehensive i18n-ready error message catalog
- `ErrorHandler.isTestEnvironment` prevents process exit during tests
- `ERROR_PAGE_CSS` contains built-in styling for error pages

More from stacksjs/stacks

SkillDescription
stacks-actionsUse when working with Stacks server actions — creating actions in app/Actions/, auto-generated API actions from the useApi model trait, the 80+ default framework actions (auth, dashboard, commerce, content, deployment, jobs), action request/response handling, or action registration. Covers @stacksjs/actions and storage/framework/defaults/actions/.
stacks-aiUse when integrating AI capabilities into a Stacks application — using Anthropic/OpenAI/Ollama/AWS Bedrock drivers, image generation (DALL-E), vision analysis, RAG/vector search, embeddings, MCP (Model Context Protocol) clients, text summarization, sentiment analysis, content classification, personalization, or the buddy AI assistant. Covers @stacksjs/ai and config/ai.ts.
stacks-aliasUse when working with path aliases in a Stacks project — import resolution, module aliasing, or debugging import paths. Covers @stacksjs/alias which defines 260+ path mappings for the entire framework.
stacks-analyticsUse when adding analytics to a Stacks application — configuring Fathom or self-hosted analytics, generating tracking scripts, privacy-friendly analytics setup, or the analytics configuration. Covers @stacksjs/analytics and config/analytics.ts.
stacks-apiUse when building, modifying, or debugging API endpoints in a Stacks application — defining routes, handling requests, API middleware, working with the API server, HTTP client (fetcher), API resources, or OpenAPI generation. Covers both @stacksjs/api utilities and the stacks-api server implementation.
stacks-arraysUse when working with array utilities in Stacks — statistical operations (average, median, mode, standard deviation, z-score, percentile, covariance), array manipulation (unique, flatten, partition, shuffle, sample, move), containment checks, or the Arr facade. Covers @stacksjs/arrays.
stacks-authUse when implementing authentication, authorization, passkeys, TOTP/2FA, RBAC, gates, policies, session auth, token management, email verification, password resets, or rate limiting in a Stacks application. Covers the @stacksjs/auth package, config/auth.ts, app/Gates.ts, and app/Middleware/.
stacks-auto-importsUse when working with the Stacks auto-import system — understanding how browser and server auto-imports work, configuring auto-imported functions/models/composables, the auto-import manifests, type generation, or how globals are injected. Covers the auto-import pipeline at storage/framework/auto-imports/.
stacks-brandkitUse when defining or exploring a brand identity for a Stacks project and you want premium brand-kit REFERENCE IMAGES first - logo directions, palettes, typography specimens, identity boards, and application/mockup decks. Generates IMAGES ONLY, never code. Trained for minimalist, cinematic, editorial, dark-tech, luxury, cultural, security, gaming, developer-tool, and consumer-app brand systems with intentional logo concepting, sparse type, strong symbolic meaning, and disciplined palettes a coding step can build against.
stacks-browseUse for headless browser QA on Stacks applications — navigation, screenshots, responsive testing, console/network monitoring, and accessibility snapshots. Dependency-free: drives a system browser over the Chrome DevTools Protocol using only Bun (no Playwright/Puppeteer). Invoke with /stacks-browse.