nuxt
Version:
65 lines (64 loc) • 2.61 kB
JavaScript
import { joinURL, withQuery } from "ufo";
import { getRequestHeaders, send, setResponseHeader, setResponseStatus } from "h3";
import { useRuntimeConfig } from "#internal/nitro";
import { useNitroApp } from "#internal/nitro/app";
import { isJsonRequest, normalizeError } from "#internal/nitro/utils";
export default (async function errorhandler(error, event) {
const { stack, statusCode, statusMessage, message } = normalizeError(error);
const errorObject = {
url: event.path,
statusCode,
statusMessage,
message,
stack: import.meta.dev && statusCode !== 404 ? `<pre>${stack.map((i) => `<span class="stack${i.internal ? " internal" : ""}">${i.text}</span>`).join("\n")}</pre>` : "",
// TODO: check and validate error.data for serialisation into query
data: error.data
};
if (error.unhandled || error.fatal) {
const tags = [
"[nuxt]",
"[request error]",
error.unhandled && "[unhandled]",
error.fatal && "[fatal]",
Number(errorObject.statusCode) !== 200 && `[${errorObject.statusCode}]`
].filter(Boolean).join(" ");
console.error(tags, errorObject.message + "\n" + stack.map((l) => " " + l.text).join(" \n"));
}
if (event.handled) {
return;
}
setResponseStatus(event, errorObject.statusCode !== 200 && errorObject.statusCode || 500, errorObject.statusMessage);
if (isJsonRequest(event)) {
setResponseHeader(event, "Content-Type", "application/json");
return send(event, JSON.stringify(errorObject));
}
const reqHeaders = getRequestHeaders(event);
const isRenderingError = event.path.startsWith("/__nuxt_error") || !!reqHeaders["x-nuxt-error"];
const res = isRenderingError ? null : await useNitroApp().localFetch(
withQuery(joinURL(useRuntimeConfig(event).app.baseURL, "/__nuxt_error"), errorObject),
{
headers: { ...reqHeaders, "x-nuxt-error": "true" },
redirect: "manual"
}
).catch(() => null);
if (!res) {
const { template } = import.meta.dev ? await import("./error-dev") : await import("./error-500");
if (import.meta.dev) {
errorObject.description = errorObject.message;
}
if (event.handled) {
return;
}
setResponseHeader(event, "Content-Type", "text/html;charset=UTF-8");
return send(event, template(errorObject));
}
const html = await res.text();
if (event.handled) {
return;
}
for (const [header, value] of res.headers.entries()) {
setResponseHeader(event, header, value);
}
setResponseStatus(event, res.status && res.status !== 200 ? res.status : void 0, res.statusText);
return send(event, html);
});