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

Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
2026-05-19 15:27:17 +00:00
3 changed files with 63 additions and 1 deletions
+16
View File
@@ -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 IntroSection from '../../../IntroSection/ui/IntroSection/IntroSection';
import ProjectsSection from '../../../ProjectsSection/ui/ProjectsSection/ProjectsSection'; import ProjectsSection from '../../../ProjectsSection/ui/ProjectsSection/ProjectsSection';
import SkillsSection from '../../../SkillsSection/ui/SkillsSection/SkillsSection'; import SkillsSection from '../../../SkillsSection/ui/SkillsSection/SkillsSection';
import { SectionErrorBoundary } from '../SectionErrorBoundary/SectionErrorBoundary';
/** /**
* Props for the SectionFactory widget. * Props for the SectionFactory widget.
@@ -36,5 +37,9 @@ export function SectionFactory({ slug }: SectionFactoryProps) {
notFound(); notFound();
} }
return <Component />; return (
<SectionErrorBoundary>
<Component />
</SectionErrorBoundary>
);
} }