UNPKG

nitropage

Version:

A free and open source, extensible visual page builder based on SolidStart.

90 lines (77 loc) 3.07 kB
import { getRequestURL, send, sendRedirect, setResponseHeader, setResponseHeaders, setResponseStatus, } from "h3"; import { NitroApp } from "../types"; const errorHandlerPlugin = (nitroApp: NitroApp) => { const origErrorHandler = nitroApp.h3App.options.onError!; nitroApp.h3App.options.onError = async (error, event) => { const url = getRequestURL(event); const referer = event.headers.get("referer"); const isServerFunction = url.pathname === "/_server" || url.pathname === "/_server/"; // TODO: Fix this in solid-start // E.g. GET-Requesting server functions results in undescriptive errors // - If referer is missing, this results in "Invalid URL": // https://github.com/solidjs/solid-start/blob/5568611d38ba30a9b03455d82e8f7a5afc0d5af8/packages/start/src/runtime/server-handler.ts#L287 // - If parsed is empty, this results in "Cannot read properties of undefined (reading 'entries')": // https://github.com/solidjs/solid-start/blob/5568611d38ba30a9b03455d82e8f7a5afc0d5af8/packages/start/src/runtime/server-handler.ts#L297 if (isServerFunction && !referer && error.message === "Invalid URL") { setResponseStatus(event, 400, "400 Bad Request"); return await send(event, ""); } const isSensitive = error.unhandled || error.fatal; if (isSensitive && import.meta.env.DEV) { console.error(error); } if (!referer || !isServerFunction) { return await origErrorHandler(error, event); } const result = await nitroApp.hooks.callHook("error", error, { event }); if (result || event.handled) { return result; } const statusMessage = error.statusMessage || "Server Error"; const errorMessage = !isSensitive || import.meta.env.DEV ? error.message : "Something went wrong"; setResponseStatus(event, error.statusCode, statusMessage); // Makes sure that the error is being catched in solid-router forms // https://github.com/solidjs/solid-start/issues/1434#issuecomment-2097769617 // https://github.com/solidjs/solid-start/blob/v1.0.0-rc.1/packages/start/src/runtime/server-handler.ts#L223 setResponseHeaders(event, { "X-Error": errorMessage.split("\n")[0], }); const acceptsHtml = event.headers.get("accept")?.startsWith("text/html"); if (!acceptsHtml) { return await send( event, JSON.stringify({ message: errorMessage, }), "application/json", ); } // Inspired by: https://github.com/solidjs/solid-start/blob/cceb4ed88c831387af94fa6a9548a401ab0ff17a/packages/start/src/runtime/server-handler.ts#L289 setResponseHeader( event, "set-cookie", `flash=${encodeURIComponent( JSON.stringify({ url: url.pathname + url.search, result: errorMessage, thrown: true, error: true, input: [], }), )}; Secure; HttpOnly;`, ); return await sendRedirect(event, referer, 302); }; }; export default errorHandlerPlugin;