错误处理

通过抛出 HTTPError 来发送错误。

H3 捕获在请求生命周期中所有可能的错误。

HTTPError

你可以使用不同的语法创建并抛出 HTTP 错误,使用 HTTPError

import { HTTPError } from "h3";

app.get("/error", (event) => {
  // 使用 message 和 details
  throw new HTTPError("无效的用户输入", { status: 400 });

  // 使用 HTTPError.status(code)
  throw HTTPError.status(400, "错误的请求");

  // 使用单个对象
  throw new HTTPError({
    status: 400,
    statusText: "错误的请求",
    message: "无效的用户输入",
    data: { field: "email" },
    body: { date: new Date().toJSON() },
    headers: {},
  });
});

这将以 400 - 错误的请求 状态码结束请求,并返回以下 JSON 响应:

{
  "date": "2025-06-05T04:20:00.0Z",
  "status": 400,
  "statusText": "错误的请求",
  "message": "无效的用户输入",
  "data": {
    "field": "email"
  }
}

HTTPError 字段

  • status:HTTP 状态码,范围在 200–599 之间。
  • statusText:要在响应头中发送的 HTTP 状态文本。
  • message:要包含在 JSON 正文中的错误消息。
  • data:附加数据,将附加在错误 JSON 正文的 data 键下。
  • body:附加的顶级属性,将附加在错误 JSON 正文中。
  • headers:错误响应中要发送的额外 HTTP 头。
  • cause:导致此错误的原始错误对象,便于追踪和调试。
  • unhandled:指示错误是否因未知原因被抛出。详见 未处理的错误
错误的 statusText 应简短(最多 512 至 1024 字符),且只包含制表符、空格、可见 ASCII 字符和扩展字符(字节值 128–255)。建议使用 JSON 正文中的 message 来扩展错误信息。

未处理的错误

在调用请求生命周期时,任何未使用 HTTPError 抛出的错误都会被视为_未处理_的错误。

app.get("/error", (event) => {
  // 这将导致未处理的错误。
  throw new Error("出了点问题");
});
为了增强安全性,H3 会在 JSON 响应中隐藏未处理错误的某些字段(databodystackmessage)。

捕获错误

使用全局 onError 钩子:

import { H3, onError } from "h3";

// 全局处理错误
const app = new H3({
  onError: (error) => {
    console.error(error);
  },
});

使用 onError 中间件 来捕获错误。

import { onError } from "h3";

// 使用中间件处理错误
app.use(
  onError(event, (event, error) => {
    console.error(error);
  }),
);
使用嵌套应用时,子应用的全局钩子不会被调用,因此最好使用 onError 中间件。