From f371178518e846d463db445d28a279febc23eabf Mon Sep 17 00:00:00 2001 From: Oronemu Date: Wed, 17 Dec 2025 21:50:10 +0700 Subject: [PATCH] 500 --- frontend/src/App.tsx | 5 + frontend/src/api/client.ts | 17 +++ frontend/src/pages/ServerErrorPage.tsx | 143 +++++++++++++++++++++++++ frontend/src/pages/index.ts | 1 + 4 files changed, 166 insertions(+) create mode 100644 frontend/src/pages/ServerErrorPage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f28c9ca..78dbf64 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -21,6 +21,7 @@ import { ProfilePage } from '@/pages/ProfilePage' import { UserProfilePage } from '@/pages/UserProfilePage' import { NotFoundPage } from '@/pages/NotFoundPage' import { TeapotPage } from '@/pages/TeapotPage' +import { ServerErrorPage } from '@/pages/ServerErrorPage' // Protected route wrapper function ProtectedRoute({ children }: { children: React.ReactNode }) { @@ -154,6 +155,10 @@ function App() { } /> } /> + {/* Server error page */} + } /> + } /> + {/* 404 - must be last */} } /> diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 5a4dfc3..c798505 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -22,11 +22,28 @@ client.interceptors.request.use((config) => { client.interceptors.response.use( (response) => response, (error: AxiosError<{ detail: string }>) => { + // Unauthorized - redirect to login if (error.response?.status === 401) { localStorage.removeItem('token') localStorage.removeItem('user') window.location.href = '/login' } + + // Server error or network error - redirect to 500 page + if ( + error.response?.status === 500 || + error.response?.status === 502 || + error.response?.status === 503 || + error.response?.status === 504 || + error.code === 'ERR_NETWORK' || + error.code === 'ECONNABORTED' + ) { + // Only redirect if not already on error page + if (!window.location.pathname.startsWith('/500') && !window.location.pathname.startsWith('/error')) { + window.location.href = '/500' + } + } + return Promise.reject(error) } ) diff --git a/frontend/src/pages/ServerErrorPage.tsx b/frontend/src/pages/ServerErrorPage.tsx new file mode 100644 index 0000000..2d98050 --- /dev/null +++ b/frontend/src/pages/ServerErrorPage.tsx @@ -0,0 +1,143 @@ +import { Link } from 'react-router-dom' +import { NeonButton } from '@/components/ui' +import { Home, Sparkles, RefreshCw, ServerCrash, Flame, Zap } from 'lucide-react' + +export function ServerErrorPage() { + const handleRefresh = () => { + window.location.href = '/' + } + + return ( +
+ {/* Background effects */} +
+
+
+
+ + {/* Server icon */} +
+ {/* Smoke/fire effect */} +
+ + + +
+ + {/* Server with error */} +
+
+ +
+ + {/* Error indicator */} +
+ +
+ + {/* Sparks */} +
+
+
+
+ + {/* Glow effect */} +
+
+ + {/* 500 text */} +
+

+ 500 +

+
+ 500 +
+
+ +

+ Ошибка сервера +

+ +

+ Что-то пошло не так на нашей стороне. +

+

+ Мы уже работаем над решением проблемы. Попробуйте обновить страницу. +

+ + {/* Status info */} +
+
+ + Internal Server Error +
+

+ Сервер временно недоступен или перегружен. Обычно это быстро исправляется. +

+
+ + {/* Buttons */} +
+ } + onClick={handleRefresh} + > + Обновить + + + }> + На главную + + +
+ + {/* Decorative sparkles */} +
+ +
+
+ +
+ + {/* Custom animations */} + +
+ ) +} diff --git a/frontend/src/pages/index.ts b/frontend/src/pages/index.ts index 3c1da62..e72cdc9 100644 --- a/frontend/src/pages/index.ts +++ b/frontend/src/pages/index.ts @@ -11,3 +11,4 @@ export { ProfilePage } from './ProfilePage' export { UserProfilePage } from './UserProfilePage' export { NotFoundPage } from './NotFoundPage' export { TeapotPage } from './TeapotPage' +export { ServerErrorPage } from './ServerErrorPage'