|
|
@@ -0,0 +1,40 @@
|
|
|
+'use client'
|
|
|
+
|
|
|
+import { useEffect, useState } from 'react'
|
|
|
+
|
|
|
+export function ErrorReporter() {
|
|
|
+ const [error, setError] = useState<string | null>(null)
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const handler = (event: ErrorEvent) => {
|
|
|
+ setError(`${event.error?.name || 'Error'}: ${event.message}\n${event.error?.stack || '(no stack)'}`)
|
|
|
+ }
|
|
|
+ const rejectionHandler = (event: PromiseRejectionEvent) => {
|
|
|
+ const err = event.reason
|
|
|
+ setError(`Unhandled Rejection: ${err?.name || 'Error'}: ${err?.message || String(err)}\n${err?.stack || '(no stack)'}`)
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('error', handler)
|
|
|
+ window.addEventListener('unhandledrejection', rejectionHandler)
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ window.removeEventListener('error', handler)
|
|
|
+ window.removeEventListener('unhandledrejection', rejectionHandler)
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ if (!error) return null
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="fixed bottom-4 left-4 right-4 z-50 max-h-[50vh] overflow-auto rounded-lg bg-red-900/90 p-4 text-white">
|
|
|
+ <p className="mb-2 font-bold">Ошибка:</p>
|
|
|
+ <pre className="whitespace-pre-wrap text-xs">{error}</pre>
|
|
|
+ <button
|
|
|
+ onClick={() => setError(null)}
|
|
|
+ className="mt-2 rounded bg-white/20 px-3 py-1 text-sm hover:bg-white/30"
|
|
|
+ >
|
|
|
+ Закрыть
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|