supersam/src/components/ErrorBoundary.jsx

93 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { logError } from '../utils/errorLogger';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
const componentInfo = {
component: errorInfo?.componentStack || null,
props: this.props,
};
logError(error, componentInfo);
}
handleRetry = () => {
this.setState({ hasError: false, error: null });
};
handleReload = () => {
window.location.reload();
};
renderDefaultFallback() {
const { compact } = this.props;
if (compact) {
return (
<div className="rounded-[24px] border border-[var(--color-error)] bg-[var(--color-error-soft)] p-4 text-center">
<p className="text-sm text-[var(--color-text)]">Что-то пошло не так</p>
<button
onClick={this.handleRetry}
className="mt-2 rounded-xl bg-[var(--color-primary)] px-4 py-2 text-sm font-semibold text-white"
>
Попробовать снова
</button>
</div>
);
}
return (
<div className="flex min-h-[460px] flex-col items-center justify-center p-8 text-center">
<div className="mb-4 text-5xl">⚠️</div>
<h2 className="mb-2 text-xl font-semibold text-[var(--color-text)]">
Что-то пошло не так
</h2>
<p className="mb-6 max-w-md text-sm text-[var(--color-text-muted)]">
Произошла непредвиденная ошибка. Попробуйте обновить страницу или вернуться позже.
</p>
{this.state.error && process.env.NODE_ENV === 'development' && (
<pre className="mb-4 max-h-32 overflow-auto rounded-xl bg-[var(--color-surface-strong)] p-3 text-left text-xs text-[var(--color-error)]">
{this.state.error.message}
</pre>
)}
<div className="flex gap-3">
<button
onClick={this.handleRetry}
className="rounded-xl bg-[var(--color-primary)] px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:opacity-90"
>
Попробовать снова
</button>
<button
onClick={this.handleReload}
className="rounded-xl border border-[var(--color-border)] px-5 py-2.5 text-sm font-semibold text-[var(--color-text)] transition-colors hover:bg-[var(--color-surface)]"
>
Обновить страницу
</button>
</div>
</div>
);
}
render() {
if (this.state.hasError) {
if (typeof this.props.fallback === 'function') {
return this.props.fallback(this.state.error, this.handleRetry);
}
return this.renderDefaultFallback();
}
return this.props.children;
}
}
export default ErrorBoundary;