From 08ed98b32baedf73b39d0ace8338ebb97937f6a4 Mon Sep 17 00:00:00 2001 From: aliang Date: Thu, 19 Dec 2024 08:30:52 +0700 Subject: [PATCH] fix(ui): handle request error in admin panel (#3589) * fix(ui): handle rate limit error * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../(dashboard)/system/components/cluster.tsx | 13 +++- ee/tabby-ui/components/error-view.tsx | 63 +++++++++++++++++++ ee/tabby-ui/lib/hooks/use-health.tsx | 4 +- ee/tabby-ui/lib/hooks/use-workers.ts | 4 +- 4 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 ee/tabby-ui/components/error-view.tsx diff --git a/ee/tabby-ui/app/(dashboard)/system/components/cluster.tsx b/ee/tabby-ui/app/(dashboard)/system/components/cluster.tsx index d0613ba44e5e..fd7dbd0d8130 100644 --- a/ee/tabby-ui/app/(dashboard)/system/components/cluster.tsx +++ b/ee/tabby-ui/app/(dashboard)/system/components/cluster.tsx @@ -19,6 +19,7 @@ import { Input } from '@/components/ui/input' import { Separator } from '@/components/ui/separator' import { Skeleton } from '@/components/ui/skeleton' import { CopyButton } from '@/components/copy-button' +import { ErrorView } from '@/components/error-view' import LoadingWrapper from '@/components/loading-wrapper' import WorkerCard from './worker-card' @@ -48,8 +49,8 @@ function toBadgeString(str: string) { } export default function Workers() { - const { data: healthInfo } = useHealth() - const { data: workers, fetching } = useWorkers() + const { data: healthInfo, error: healthError } = useHealth() + const { data: workers, isLoading, error: workersError } = useWorkers() const [{ data: registrationTokenRes }, reexecuteQuery] = useQuery({ query: getRegistrationTokenDocument }) @@ -60,6 +61,12 @@ export default function Workers() { } }) + const error = healthError || workersError + + if (error) { + return + } + if (!healthInfo) return return ( @@ -84,7 +91,7 @@ export default function Workers() { } > <> diff --git a/ee/tabby-ui/components/error-view.tsx b/ee/tabby-ui/components/error-view.tsx new file mode 100644 index 000000000000..6892872eeb9e --- /dev/null +++ b/ee/tabby-ui/components/error-view.tsx @@ -0,0 +1,63 @@ +'use client' + +import { ReactNode } from 'react' + +import { cn } from '@/lib/utils' +import { Button } from '@/components/ui/button' + +export function ErrorView({ + title, + description, + className, + children, + statusText, + hideChildren +}: { + title?: string + description?: string + className?: string + hideChildren?: boolean + children?: ReactNode + statusText?: string +}) { + let defaultTitle = 'Something went wrong' + let defaultDescription = 'Oops! Please try again later.' + let displayTitle = '' + let displayDescription = description || defaultDescription + + switch (statusText) { + case 'Too Many Requests': + displayTitle = 'Too Many Requests' + break + case 'Bad Request': + displayTitle = 'Bad Request' + break + default: + displayTitle = title || defaultTitle + } + + return ( +
+

+ {displayTitle} +

+ {!!displayDescription && ( +

{displayDescription}

+ )} + {!hideChildren && ( +
+ {children ? ( + children + ) : ( + + )} +
+ )} +
+ ) +} diff --git a/ee/tabby-ui/lib/hooks/use-health.tsx b/ee/tabby-ui/lib/hooks/use-health.tsx index faff42d55359..ae9da1563fb8 100644 --- a/ee/tabby-ui/lib/hooks/use-health.tsx +++ b/ee/tabby-ui/lib/hooks/use-health.tsx @@ -23,8 +23,8 @@ export function useHealth(): SWRResponse { '/v1/health', (url: string) => { return fetcher(url, { - errorHandler: () => { - throw new Error('Unhealth') + errorHandler: response => { + throw new Error(response?.statusText.toString() || 'Unhealth') } }) }, diff --git a/ee/tabby-ui/lib/hooks/use-workers.ts b/ee/tabby-ui/lib/hooks/use-workers.ts index 70a7fb20a0d2..b17545930b4b 100644 --- a/ee/tabby-ui/lib/hooks/use-workers.ts +++ b/ee/tabby-ui/lib/hooks/use-workers.ts @@ -31,7 +31,7 @@ function transformHealthInfoToChatWorker(healthInfo: HealthInfo) { } function useWorkers() { - const { data: healthInfo, isLoading: fetching } = useHealth() + const { data: healthInfo, isLoading, error } = useHealth() const groupedWorkers = React.useMemo(() => { const workers = [] @@ -45,7 +45,7 @@ function useWorkers() { return groupBy(workers, 'kind') }, [healthInfo]) - return { data: groupedWorkers, fetching } + return { data: groupedWorkers, isLoading, error } } export { useWorkers }