Files
sam-react-prod/src/components/providers/ChunkErrorHandler.tsx

69 lines
1.9 KiB
TypeScript
Raw Normal View History

'use client';
import { useEffect } from 'react';
import { reportErrorToSlack } from '@/lib/error-reporting';
/**
* ChunkLoadError
*
* JS Slack으로
* - window 'error' : <script>
* - window 'unhandledrejection': dynamic import()
*/
const CHUNK_ERROR_PATTERNS = [
'Loading chunk',
'ChunkLoadError',
'Failed to fetch dynamically imported module',
'error loading dynamically imported module',
];
function isChunkError(message: string): boolean {
return CHUNK_ERROR_PATTERNS.some((pattern) =>
message.toLowerCase().includes(pattern.toLowerCase())
);
}
function sendReport(message: string, stack?: string) {
reportErrorToSlack({
errorType: 'CHUNK_LOAD_ERROR',
message,
pageUrl: window.location.href,
timestamp: new Date().toISOString(),
stack: stack?.slice(0, 500),
userAgent: navigator.userAgent,
});
}
export function ChunkErrorHandler() {
useEffect(() => {
function handleError(event: ErrorEvent) {
if (event.message && isChunkError(event.message)) {
sendReport(event.message, event.error?.stack);
}
}
function handleRejection(event: PromiseRejectionEvent) {
const reason = event.reason;
const message =
reason instanceof Error ? reason.message : String(reason ?? '');
if (isChunkError(message)) {
sendReport(
message,
reason instanceof Error ? reason.stack?.slice(0, 500) : undefined
);
}
}
window.addEventListener('error', handleError);
window.addEventListener('unhandledrejection', handleRejection);
return () => {
window.removeEventListener('error', handleError);
window.removeEventListener('unhandledrejection', handleRejection);
};
}, []);
return null;
}