Merge pull request 'feat: add route-level error page and per-section error boundary' (#3) from feature/error-handling into main
Build and push / build (push) Failing after 22s
Build and push / build (push) Failing after 22s
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { Link } from '$shared/ui';
|
||||
|
||||
/**
|
||||
* Route-level error boundary — shown when an unhandled error escapes
|
||||
* the [[...slug]] segment. Mirrors the not-found layout.
|
||||
*/
|
||||
export default function ErrorPage() {
|
||||
return (
|
||||
<main className="flex-1 flex flex-col items-center justify-center gap-6">
|
||||
<h1 className="font-heading text-[clamp(8rem,20vw,18rem)] leading-none">500</h1>
|
||||
<Link href="/">Back to main</Link>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
'use client';
|
||||
|
||||
import type { ErrorInfo, ReactNode } from 'react';
|
||||
import { Component } from 'react';
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
* Section content to render
|
||||
*/
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
type State = {
|
||||
/**
|
||||
* Whether an error was caught
|
||||
*/
|
||||
hasError: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Isolates a single section's render errors so a broken section
|
||||
* does not crash the rest of the page.
|
||||
*/
|
||||
export class SectionErrorBoundary extends Component<Props, State> {
|
||||
state: State = { hasError: false };
|
||||
|
||||
static getDerivedStateFromError(): State {
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
override componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
console.error('[SectionErrorBoundary]', error, info.componentStack);
|
||||
}
|
||||
|
||||
override render() {
|
||||
if (this.state.hasError) {
|
||||
return null;
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import ExperienceSection from '../../../ExperienceSection/ui/ExperienceSection/E
|
||||
import IntroSection from '../../../IntroSection/ui/IntroSection/IntroSection';
|
||||
import ProjectsSection from '../../../ProjectsSection/ui/ProjectsSection/ProjectsSection';
|
||||
import SkillsSection from '../../../SkillsSection/ui/SkillsSection/SkillsSection';
|
||||
import { SectionErrorBoundary } from '../SectionErrorBoundary/SectionErrorBoundary';
|
||||
|
||||
/**
|
||||
* Props for the SectionFactory widget.
|
||||
@@ -36,5 +37,9 @@ export function SectionFactory({ slug }: SectionFactoryProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return <Component />;
|
||||
return (
|
||||
<SectionErrorBoundary>
|
||||
<Component />
|
||||
</SectionErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user