UNPKG

@tanstack/vue-router

Version:

Modern and scalable routing for Vue applications

101 lines (100 loc) 2.7 kB
import { renderInNonRouteComponentContext } from "./nonRouteComponentContext.js"; import * as Vue from "vue"; //#region src/CatchBoundary.tsx var VueErrorBoundary = Vue.defineComponent({ name: "VueErrorBoundary", props: { onError: Function, resetKey: [ String, Number, Object ], children: null, errorComponent: null }, setup(props) { const error = Vue.ref(null); const reset = () => { error.value = null; }; Vue.watch(() => props.resetKey, (newKey, oldKey) => { if (newKey !== oldKey && error.value) reset(); }); Vue.onErrorCaptured((err) => { if (err instanceof Promise || err && typeof err.then === "function") return false; error.value = err; if (props.onError) props.onError(err); return false; }); return () => { if (!error.value) return props.children; const errorComponent = props.errorComponent ?? ErrorComponent; const errorProps = { error: error.value, reset }; return process.env.NODE_ENV !== "production" ? renderInNonRouteComponentContext(errorComponent, errorProps, "errorComponent") : Vue.h(errorComponent, errorProps); }; } }); function CatchBoundary(props) { return Vue.h(VueErrorBoundary, { resetKey: props.getResetKey(), onError: props.onCatch, children: props.children, errorComponent: props.errorComponent }); } CatchBoundary.inheritAttrs = false; CatchBoundary.props = [ "getResetKey", "children", "errorComponent", "onCatch" ]; var ErrorComponent = Vue.defineComponent({ name: "ErrorComponent", props: { error: Object, reset: Function }, setup(props) { const show = Vue.ref(process.env.NODE_ENV !== "production"); const toggleShow = () => { show.value = !show.value; }; return () => Vue.h("div", { style: { padding: ".5rem", maxWidth: "100%" } }, [ Vue.h("div", { style: { display: "flex", alignItems: "center", gap: ".5rem" } }, [Vue.h("strong", { style: { fontSize: "1rem" } }, "Something went wrong!"), Vue.h("button", { style: { appearance: "none", fontSize: ".6em", border: "1px solid currentColor", padding: ".1rem .2rem", fontWeight: "bold", borderRadius: ".25rem" }, onClick: toggleShow }, show.value ? "Hide Error" : "Show Error")]), Vue.h("div", { style: { height: ".25rem" } }), show.value ? Vue.h("div", {}, [Vue.h("pre", { style: { fontSize: ".7em", border: "1px solid red", borderRadius: ".25rem", padding: ".3rem", color: "red", overflow: "auto" } }, [props.error?.message ? Vue.h("code", {}, props.error.message) : null])]) : null ]); } }); //#endregion export { CatchBoundary, ErrorComponent }; //# sourceMappingURL=CatchBoundary.js.map