fix: show error message on login page when backend is unreachable (#2063)

This commit is contained in:
Nody the lobster
2026-03-14 07:20:01 -04:00
committed by GitHub
parent 351350ea03
commit eed72b1c12
5 changed files with 78 additions and 2 deletions

View File

@@ -23,7 +23,7 @@ import {
import { useEffect, useState } from 'react';
import { httpClient, initializeUserInfo } from '@/app/infra/http';
import { useRouter } from 'next/navigation';
import { Mail, Lock, Loader2 } from 'lucide-react';
import { Mail, Lock, Loader2, AlertCircle, RefreshCw } from 'lucide-react';
import langbotIcon from '@/app/assets/langbot-logo.webp';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
@@ -46,6 +46,8 @@ export default function Login() {
const [accountType, setAccountType] = useState<AccountType | null>(null);
const [hasPassword, setHasPassword] = useState(false);
const [loading, setLoading] = useState(true);
const [loadError, setLoadError] = useState<string | null>(null);
const [retrying, setRetrying] = useState(false);
const form = useForm<z.infer<ReturnType<typeof formSchema>>>({
resolver: zodResolver(formSchema(t)),
@@ -61,6 +63,7 @@ export default function Login() {
async function checkAccountInfo() {
try {
setLoadError(null);
const res = await httpClient.getAccountInfo();
if (!res.initialized) {
router.push('/register');
@@ -72,11 +75,22 @@ export default function Login() {
// Also check if already logged in
checkIfAlreadyLoggedIn();
} catch {
} catch (err) {
const errorMessage =
err instanceof Error ? err.message : t('common.loginLoadError');
setLoadError(errorMessage);
setLoading(false);
}
}
async function handleRetry() {
setRetrying(true);
setLoading(true);
setLoadError(null);
await checkAccountInfo();
setRetrying(false);
}
function checkIfAlreadyLoggedIn() {
httpClient
.checkUserToken()
@@ -129,6 +143,54 @@ export default function Login() {
);
}
// Show error state when account info failed to load
if (loadError) {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-neutral-900">
<Card className="w-[375px] shadow-lg dark:shadow-white/10">
<CardHeader>
<div className="flex justify-between items-center mb-6">
<ThemeToggle />
<LanguageSelector />
</div>
<img
src={langbotIcon.src}
alt="LangBot"
className="w-16 h-16 mb-4 mx-auto"
/>
<CardTitle className="text-2xl text-center">
{t('common.welcome')}
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex flex-col items-center gap-3 py-4">
<AlertCircle className="h-10 w-10 text-destructive" />
<p className="text-sm text-center text-muted-foreground">
{t('common.loginLoadErrorDesc')}
</p>
<code className="text-xs bg-muted px-3 py-2 rounded max-w-full overflow-x-auto block text-center text-muted-foreground">
{loadError}
</code>
<Button
onClick={handleRetry}
disabled={retrying}
variant="outline"
className="mt-2 cursor-pointer"
>
{retrying ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : (
<RefreshCw className="mr-2 h-4 w-4" />
)}
{t('common.retry')}
</Button>
</div>
</CardContent>
</Card>
</div>
);
}
// Determine what to show based on account type
const showLocalLogin =
accountType === 'local' || (accountType === 'space' && hasPassword);

View File

@@ -11,6 +11,10 @@ const enUS = {
continueToLogin: 'Login to continue',
loginSuccess: 'Login successful',
loginFailed: 'Login failed, please check your email and password',
loginLoadError: 'Unable to connect to server',
loginLoadErrorDesc:
'Unable to connect to the LangBot backend. Please make sure the service is running and try again.',
retry: 'Retry',
enterEmail: 'Enter email address',
enterPassword: 'Enter password',
invalidEmail: 'Please enter a valid email address',

View File

@@ -12,6 +12,10 @@
loginSuccess: 'ログインに成功しました',
loginFailed:
'ログインに失敗しました。メールアドレスまたはパスワードをご確認ください',
loginLoadError: 'サーバーに接続できません',
loginLoadErrorDesc:
'LangBot バックエンドに接続できません。サービスが起動していることを確認してから再試行してください。',
retry: '再試行',
enterEmail: 'メールアドレスを入力',
enterPassword: 'パスワードを入力',
invalidEmail: '有効なメールアドレスを入力してください',

View File

@@ -11,6 +11,9 @@ const zhHans = {
continueToLogin: '登录以继续',
loginSuccess: '登录成功',
loginFailed: '登录失败,请检查邮箱和密码是否正确',
loginLoadError: '无法连接到服务器',
loginLoadErrorDesc: '无法连接到 LangBot 后端服务,请确认服务已启动后重试。',
retry: '重试',
enterEmail: '输入邮箱地址',
enterPassword: '输入密码',
invalidEmail: '请输入有效的邮箱地址',

View File

@@ -11,6 +11,9 @@ const zhHant = {
continueToLogin: '登入以繼續',
loginSuccess: '登入成功',
loginFailed: '登入失敗,請檢查電子郵件和密碼是否正確',
loginLoadError: '無法連線到伺服器',
loginLoadErrorDesc: '無法連線到 LangBot 後端服務,請確認服務已啟動後重試。',
retry: '重試',
enterEmail: '輸入電子郵件地址',
enterPassword: '輸入密碼',
invalidEmail: '請輸入有效的電子郵件地址',