@critters/next
Version:
Secure bug reporting library for Next.js applications
109 lines (108 loc) • 3.85 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorBoundary = void 0;
exports.withErrorBoundary = withErrorBoundary;
exports.useErrorReporting = useErrorReporting;
const react_1 = __importDefault(require("react"));
const reporter_1 = require("./reporter");
/**
* Create a wrapper for React components to catch and report errors
*/
function withErrorBoundary(Component, options = {}) {
return function ErrorBoundaryWrapper(props) {
// Skip error boundary in server-side rendering
if (typeof window === "undefined") {
return react_1.default.createElement(Component, Object.assign({}, props));
}
class ErrorBoundary extends react_1.default.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
const metadata = {
componentStack: errorInfo.componentStack,
errorBoundary: {
name: Component.displayName || Component.name || "Unknown",
},
};
// Capture props if enabled
if (options.captureProps) {
metadata.props = props;
}
// Report the error
reporter_1.Critters.getInstance().catch(error, metadata);
// Call the onError callback if provided
if (options.onError) {
options.onError(error, errorInfo);
}
}
render() {
if (this.state.hasError) {
return options.fallback || react_1.default.createElement("div", null, "Something went wrong.");
}
return this.props.children;
}
}
return (react_1.default.createElement(ErrorBoundary, null,
react_1.default.createElement(Component, Object.assign({}, props))));
};
}
/**
* Error boundary component for wrapping components
*/
class ErrorBoundary extends react_1.default.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
const metadata = {
componentStack: errorInfo.componentStack,
};
// Capture props if enabled
if (this.props.captureProps) {
metadata.props = this.props.children;
}
// Capture state if enabled
if (this.props.captureState && this.state) {
metadata.state = this.state;
}
// Report the error
reporter_1.Critters.getInstance().catch(error, metadata);
// Call the onError callback if provided
if (this.props.onError) {
this.props.onError(error, errorInfo);
}
}
render() {
if (this.state.hasError) {
return this.props.fallback || react_1.default.createElement("div", null, "Something went wrong.");
}
return this.props.children;
}
}
exports.ErrorBoundary = ErrorBoundary;
/**
* Hook for manual error reporting
*/
function useErrorReporting() {
const reporter = reporter_1.Critters.getInstance();
return {
reportError: (error, metadata) => {
return reporter.catch(error, metadata);
},
catch: (error, metadata) => {
return reporter.catch(error, metadata);
},
};
}