UNPKG

nuxt

Version:

Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.

65 lines (64 loc) 2.61 kB
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); });