From 57355fae1ff20e7752d0be181b52ccdba61741c8 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 8 Aug 2024 10:58:03 -0500 Subject: [PATCH] Better error handling. --- src/AuthAwareQueryClientProvider.tsx | 16 +++++++--------- src/api/getRecipe.ts | 4 ---- src/routes/recipes_/$username.$slug.tsx | 13 +++++++++++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/AuthAwareQueryClientProvider.tsx b/src/AuthAwareQueryClientProvider.tsx index 85eab04..82ca3fa 100644 --- a/src/AuthAwareQueryClientProvider.tsx +++ b/src/AuthAwareQueryClientProvider.tsx @@ -1,19 +1,14 @@ -import { - QueryCache, - QueryClient, - QueryClientProvider -} from '@tanstack/react-query' +import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { useRouter } from '@tanstack/react-router' import React, { useState } from 'react' +import { ApiError } from './api/ApiError' import ExpiredTokenError from './api/ExpiredTokenError' import refresh, { ExpiredRefreshTokenError } from './api/refresh' import LoginView from './api/types/LoginView' import { useAuth } from './auth' -const AuthAwareQueryClientProvider = ({ - children -}: React.PropsWithChildren) => { +const AuthAwareQueryClientProvider = ({ children }: React.PropsWithChildren) => { const { putToken, clearToken } = useAuth() const router = useRouter() const [currentlyRefreshing, setCurrentlyRefreshing] = useState(false) @@ -56,7 +51,10 @@ const AuthAwareQueryClientProvider = ({ defaultOptions: { queries: { retry(failureCount, error) { - if (error instanceof ExpiredTokenError) { + if ( + error instanceof ExpiredTokenError || + (error instanceof ApiError && error.status === 404) + ) { return false } else { return failureCount <= 3 diff --git a/src/api/getRecipe.ts b/src/api/getRecipe.ts index 7d5eb95..5b8a5f0 100644 --- a/src/api/getRecipe.ts +++ b/src/api/getRecipe.ts @@ -1,4 +1,3 @@ -import { notFound } from '@tanstack/react-router' import { AuthContextType } from '../auth' import { ApiError } from './ApiError' import ExpiredTokenError from './ExpiredTokenError' @@ -25,9 +24,6 @@ const getRecipe = async ({ authContext, username, slug, abortSignal }: GetRecipe return toFullRecipeView((await response.json()) as RawFullRecipeView) } else if (response.status === 401) { throw new ExpiredTokenError() - } else if (response.status === 404) { - // no such resource - throw notFound() } else { throw new ApiError(response.status, response.statusText) } diff --git a/src/routes/recipes_/$username.$slug.tsx b/src/routes/recipes_/$username.$slug.tsx index 1908d2e..2cf119a 100644 --- a/src/routes/recipes_/$username.$slug.tsx +++ b/src/routes/recipes_/$username.$slug.tsx @@ -1,9 +1,10 @@ import { useQuery, useQueryClient } from '@tanstack/react-query' import { createFileRoute, useParams } from '@tanstack/react-router' +import { ApiError } from '../../api/ApiError' +import getImage from '../../api/getImage' import getRecipe from '../../api/getRecipe' import { useAuth } from '../../auth' import Recipe from '../../pages/recipe/Recipe' -import getImage from '../../api/getImage' export const Route = createFileRoute('/recipes/$username/$slug')({ component() { @@ -52,7 +53,15 @@ export const Route = createFileRoute('/recipes/$username/$slug')({ if (isLoading || isImageLoading) { return 'Loading...' } else if (error !== null) { - return `Error: ${error.name} ${error.message}` + if (error instanceof ApiError) { + if (error.status === 404) { + return `No such recipe.` + } else { + return `ApiError: ${error.status} ${error.message}` + } + } else { + return `Error: ${error.name} ${error.message}` + } } else if (imageError !== null) { return `Image loading error: ${imageError} ${imageError.message}` } else if (recipe !== undefined && imgUrl !== undefined) {