diff --git a/src/app/page.tsx b/src/app/page.tsx index 1e64fc6..286d683 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -8,6 +8,7 @@ import TimeSeriesChart from '@/components/charts/TimeSeriesChart'; import NetworkChart from '@/components/charts/NetworkChart'; import NodeTable from '@/components/report/NodeTable'; import AlertSection from '@/components/report/AlertSection'; +import ErrorBoundary from '@/components/ErrorBoundary'; export default function Home() { const [days, setDays] = useState(7); @@ -51,7 +52,7 @@ export default function Home() { if (error || !data) { return (
-
데이터 로딩 실패: {error?.message}
+
데이터 로딩 실패: {String(error)}
); } @@ -59,11 +60,13 @@ export default function Home() { return (
- + + +
{[1, 3, 7, 14, 30].map((d) => ( @@ -79,41 +82,57 @@ export default function Home() { ))}
- + + + - - - + + + + + + + + + - {data.metrics.nas.length > 0 && ( - + {data.metrics.nas && data.metrics.nas.length > 0 && ( + + + )} - + + + -
-

노드별 상세

- -
+ +
+

노드별 상세

+ +
+
-
-

주의 구간

- -
+ +
+

주의 구간

+ +
+
); diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx new file mode 100644 index 0000000..7b9fb51 --- /dev/null +++ b/src/components/ErrorBoundary.tsx @@ -0,0 +1,37 @@ +'use client'; + +import { Component, ReactNode } from 'react'; + +interface Props { + children: ReactNode; + fallback?: string; +} + +interface State { + hasError: boolean; + error: Error | null; +} + +export default class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + render() { + if (this.state.hasError) { + return ( +
+

{this.props.fallback || '컴포넌트 렌더링 오류'}

+

{this.state.error?.message}

+
{this.state.error?.stack}
+
+ ); + } + return this.props.children; + } +} diff --git a/src/components/charts/NetworkChart.tsx b/src/components/charts/NetworkChart.tsx index bd14d05..7a11a24 100644 --- a/src/components/charts/NetworkChart.tsx +++ b/src/components/charts/NetworkChart.tsx @@ -4,7 +4,7 @@ import dynamic from 'next/dynamic'; import type { NetworkMetrics } from '@/types/metrics'; import { formatTimestamp, formatBytes } from '@/lib/formatters'; -const ReactECharts = dynamic(() => import('echarts-for-react'), { ssr: false }); +const ReactECharts = dynamic(() => import('echarts-for-react').then(mod => mod), { ssr: false, loading: () =>
}); interface NetworkChartProps { data: NetworkMetrics; diff --git a/src/components/charts/TimeSeriesChart.tsx b/src/components/charts/TimeSeriesChart.tsx index 1563c25..8614c01 100644 --- a/src/components/charts/TimeSeriesChart.tsx +++ b/src/components/charts/TimeSeriesChart.tsx @@ -4,7 +4,7 @@ import dynamic from 'next/dynamic'; import type { MetricInstance } from '@/types/metrics'; import { formatTimestamp } from '@/lib/formatters'; -const ReactECharts = dynamic(() => import('echarts-for-react'), { ssr: false }); +const ReactECharts = dynamic(() => import('echarts-for-react').then(mod => mod), { ssr: false, loading: () =>
}); interface TimeSeriesChartProps { title: string;