# 错误处理

URL: https://caijiao.org/hono/02-core/04-error-handling
Source: docs/hono/02-core/04-error-handling.md
Description: 学习 Hono 中的 notFound、onError、HTTPException、自定义错误响应和接口错误设计。

接口错误要同时照顾开发者调试和客户端消费。Hono 提供 `app.notFound()`、`app.onError()` 和 `HTTPException` 等方式处理错误。

## 404 处理

```ts
app.notFound((c) => {
  return c.json(
    {
      message: 'Not Found',
      path: c.req.path,
    },
    404,
  )
})
```

如果你的服务是纯 API，建议统一返回 JSON。不要让部分接口返回 HTML 404，部分接口返回 JSON 404。

## 全局错误处理

```ts
app.onError((err, c) => {
  console.error(err)

  return c.json(
    {
      message: 'Internal Server Error',
    },
    500,
  )
})
```

生产环境不要把完整错误堆栈返回给客户端。堆栈应该进入日志或错误追踪系统。

## 使用 HTTPException

`HTTPException` 适合在深层函数或中间件中抛出带状态码的错误：

```ts
import { HTTPException } from 'hono/http-exception'

app.get('/me', (c) => {
  const token = c.req.header('Authorization')

  if (!token) {
    throw new HTTPException(401, { message: 'Missing token' })
  }

  return c.json({ id: 1 })
})
```

在 `onError` 中识别它：

```ts
import { HTTPException } from 'hono/http-exception'

app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return err.getResponse()
  }

  console.error(err)
  return c.json({ message: 'Internal Server Error' }, 500)
})
```

如果需要统一 JSON 格式，可以不直接返回 `err.getResponse()`，而是读取状态和消息后自行构造响应。

## 业务错误格式

一个简单稳定的 API 错误格式：

```json
{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "用户不存在"
  }
}
```

对应工具函数：

```ts
function errorResponse(c, code: string, message: string, status = 400) {
  return c.json(
    {
      error: { code, message },
    },
    status,
  )
}
```

使用：

```ts
app.get('/users/:id', (c) => {
  const user = null

  if (!user) {
    return errorResponse(c, 'USER_NOT_FOUND', '用户不存在', 404)
  }

  return c.json(user)
})
```

## 错误处理建议

- 客户端输入错误用 `400`，未登录用 `401`，无权限用 `403`，资源不存在用 `404`。
- 服务器内部异常用 `500`，不要为了“请求成功到达”而返回 `200`。
- 验证错误要指出字段和原因，但不要泄露安全敏感信息。
- 统一错误格式，方便前端、客户端 SDK 和监控系统处理。
