Error Handling
Send errors by throwing an HTTPError.
H3 captures all possible errors during request lifecycle.
HTTPError
You can create and throw HTTP errors using HTTPError
with different syntaxes.
import { HTTPError } from "h3";
app.get("/error", (event) => {
// Using message and details
throw new HTTPError("Invalid user input", { status: 400 });
// Using HTTPError.status(code)
throw HTTPError.status(400, "Bad Request");
// Using single pbject
throw new HTTPError({
status: 400,
statusText: "Bad Request",
message: "Invalid user input",
data: { field: "email" },
body: { date: new Date().toJSON() },
headers: {},
});
});
This will end the request with 400 - Bad Request
status code and the following JSON response:
{
"date": "2025-06-05T04:20:00.0Z",
"status": 400,
"statusText": "Bad Request",
"message": "Invalid user input",
"data": {
"field": "email"
}
}
HTTPError
Fields
status
: HTTP status code in the range 200–599.statusText
: HTTP status text to be sent in the response header.message
: Error message to be included in the JSON body.data
: Additional data to be attached under thedata
key in the error JSON body.body
: Additional top-level properties to be attached in the error JSON body.headers
: Additional HTTP headers to be sent in the error response.cause
: The original error object that caused this error, useful for tracing and debugging.unhandled
: Indicates whether the error was thrown for unknown reasons. See Unhandled Errors.
Error
statusText
should be short (max 512 to 1024 characters) and only include tab, spaces or visible ASCII characters and extended characters (byte value 128–255). Prefer message
in JSON body for extended message.Unhandled Errors
Any error that occurs during calling request lifecycle without using HTTPError
will be processed as an unhandled error.
app.get("/error", (event) => {
// This will cause an unhandled error.
throw new Error("Something went wrong");
});
For enhanced security, H3 hides certain fields of unhandled errors (
data
, body
, stack
and message
) in JSON response.Catching Errors
Using global onError
hook:
import { H3, onError } from "h3";
// Globally handling errors
const app = new H3({
onError: (error) => {
console.error(error);
},
});
Using onError
middleware to catch errors.
import { onError } from "h3";
// Handling errors using middleware
app.use(
onError(event, (event, error) => {
console.error(error);
}),
);
When using nested apps, global hooks of sub-apps will not be called. Therefore it is better to use
onError
middleware.