@tanstack/vue-router
Version:
Modern and scalable routing for Vue applications
118 lines (117 loc) • 3.11 kB
JavaScript
import * as Vue from "vue";
//#region src/CatchBoundary.tsx
var VueErrorBoundary = Vue.defineComponent({
name: "VueErrorBoundary",
props: {
onError: Function,
resetKey: [String, Number]
},
emits: ["catch"],
setup(props, { slots }) {
const error = Vue.ref(null);
const resetFn = 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;
resetFn.value = reset;
if (props.onError) props.onError(err);
return false;
});
return () => {
if (error.value && slots.fallback) {
const fallbackContent = slots.fallback({
error: error.value,
reset
});
return Array.isArray(fallbackContent) && fallbackContent.length === 1 ? fallbackContent[0] : fallbackContent;
}
const defaultContent = slots.default && slots.default();
return Array.isArray(defaultContent) && defaultContent.length === 1 ? defaultContent[0] : defaultContent;
};
}
});
var CatchBoundaryWrapper = Vue.defineComponent({
name: "CatchBoundary",
inheritAttrs: false,
props: [
"getResetKey",
"children",
"errorComponent",
"onCatch"
],
setup(props) {
const resetKey = Vue.computed(() => props.getResetKey());
return () => {
return Vue.h(VueErrorBoundary, {
resetKey: resetKey.value,
onError: props.onCatch
}, {
default: () => props.children,
fallback: ({ error, reset }) => {
if (props.errorComponent) return Vue.h(props.errorComponent, {
error,
reset
});
return Vue.h(ErrorComponent, {
error,
reset
});
}
});
};
}
});
function CatchBoundary(props) {
return Vue.h(CatchBoundaryWrapper, props);
}
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