# Error Handling

> 

Horn gives you app-level and route-level error boundaries.

## App-level fallback

Use `app/error.vue` for the broadest fallback. It renders when no nearer route boundary handles the failure.

## Route-level boundaries

Use `app/pages/**/error.*` for route-local errors.

These boundaries are the right place for:

- loader failures
- action failures
- render-time failures inside a route subtree

## Error responses

Loaders and actions can return `Response` objects directly, or helper responses via:

- `json()`
- `redirect()`
- `badRequest()`

## Operational hooks

If you need request-level logging or mutation guards, use middleware instead of pushing that logic into every loader or action.
