UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

71 lines (70 loc) 3.2 kB
export { getBetterError }; // TO-DO/maybe: make it a library `@brillout/better-error` // Copies: // - https://github.com/brillout/react-streaming/blob/b8565c1257c63a665bda31b9be42112e458859d1/src/utils/getBetterError.ts // - https://github.com/vikejs/vike-react/blob/5477461e67592e24d2aa38a552703b9e76a01d2a/packages/vike-react/src/utils/getBetterErrorLight.ts import { isObject } from './isObject.js'; import { assertIsNotBrowser } from './assertIsNotBrowser.js'; import { objectAssign } from './objectAssign.js'; import { shallowClone } from './shallowClone.js'; assertIsNotBrowser(); function getBetterError(err, modifications) { const errOriginal = shallowClone(err); let errBetter; // Normalize if (!isObject(err)) { warnMalformed(errOriginal); errBetter = new Error(String(err)); } else { // We mutate instead of structuredClone(err) to avoid breaking Vite's ssrFixStacktrace() internal rewroteStacktraces.has(err) check // https://github.com/vitejs/vite/blob/dafd726032daa98d0e614f97aebe9d4dbffe2ea7/packages/vite/src/node/ssr/ssrStacktrace.ts#L95 errBetter = err; } errBetter.message ?? (errBetter.message = ''); if (!errBetter.stack) { warnMalformed(errOriginal); errBetter.stack = new Error(errBetter.message).stack; } // Modifications: err.hideStack and err.stack const { message: modsMessage, ...mods } = modifications; Object.assign(errBetter, mods); // Modifications: err.message if (typeof modsMessage === 'string') { // Modify err.message const messagePrev = errBetter.message; const messageNext = modsMessage; errBetter.message = messageNext; // Update err.stack const messagePrevIdx = errBetter.stack.indexOf(messagePrev); if (messagePrevIdx >= 0) { // Completely replace the beginning of err.stack — removing prefix such as "SyntaxError: " // - Following isn't always true: `err.stack.startsWith(err.message)` — because err.stack can start with "SyntaxError: " whereas err.message doesn't const stack = errBetter.stack.slice(messagePrevIdx + messagePrev.length); errBetter.stack = messageNext + stack; } else { warnMalformed(errOriginal); } } else { if (modsMessage?.append) { const messagePrev = errBetter.message; const messageNext = errBetter.message + modsMessage.append; errBetter.message = messageNext; errBetter.stack = errBetter.stack.replace(messagePrev, messageNext); } if (modsMessage?.prepend) { const { prepend } = modsMessage; errBetter.message = prepend + errBetter.message; errBetter.stack = prepend + errBetter.stack; } } // Enable users to retrieve the original error objectAssign(errBetter, { getOriginalError: () => errOriginal?.getOriginalError?.() ?? errOriginal }); return errBetter; } // TO-DO/eventually: think about whether logging this warning is a good idea function warnMalformed(errOriginal) { console.warn('Malformed error: ', errOriginal); }