Better error handling.

This commit is contained in:
Jesse Brault 2024-08-08 10:58:03 -05:00
parent 111acea22f
commit 57355fae1f
3 changed files with 18 additions and 15 deletions

View File

@ -1,19 +1,14 @@
import { import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'
QueryCache,
QueryClient,
QueryClientProvider
} from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { useRouter } from '@tanstack/react-router' import { useRouter } from '@tanstack/react-router'
import React, { useState } from 'react' import React, { useState } from 'react'
import { ApiError } from './api/ApiError'
import ExpiredTokenError from './api/ExpiredTokenError' import ExpiredTokenError from './api/ExpiredTokenError'
import refresh, { ExpiredRefreshTokenError } from './api/refresh' import refresh, { ExpiredRefreshTokenError } from './api/refresh'
import LoginView from './api/types/LoginView' import LoginView from './api/types/LoginView'
import { useAuth } from './auth' import { useAuth } from './auth'
const AuthAwareQueryClientProvider = ({ const AuthAwareQueryClientProvider = ({ children }: React.PropsWithChildren) => {
children
}: React.PropsWithChildren) => {
const { putToken, clearToken } = useAuth() const { putToken, clearToken } = useAuth()
const router = useRouter() const router = useRouter()
const [currentlyRefreshing, setCurrentlyRefreshing] = useState(false) const [currentlyRefreshing, setCurrentlyRefreshing] = useState(false)
@ -56,7 +51,10 @@ const AuthAwareQueryClientProvider = ({
defaultOptions: { defaultOptions: {
queries: { queries: {
retry(failureCount, error) { retry(failureCount, error) {
if (error instanceof ExpiredTokenError) { if (
error instanceof ExpiredTokenError ||
(error instanceof ApiError && error.status === 404)
) {
return false return false
} else { } else {
return failureCount <= 3 return failureCount <= 3

View File

@ -1,4 +1,3 @@
import { notFound } from '@tanstack/react-router'
import { AuthContextType } from '../auth' import { AuthContextType } from '../auth'
import { ApiError } from './ApiError' import { ApiError } from './ApiError'
import ExpiredTokenError from './ExpiredTokenError' import ExpiredTokenError from './ExpiredTokenError'
@ -25,9 +24,6 @@ const getRecipe = async ({ authContext, username, slug, abortSignal }: GetRecipe
return toFullRecipeView((await response.json()) as RawFullRecipeView) return toFullRecipeView((await response.json()) as RawFullRecipeView)
} else if (response.status === 401) { } else if (response.status === 401) {
throw new ExpiredTokenError() throw new ExpiredTokenError()
} else if (response.status === 404) {
// no such resource
throw notFound()
} else { } else {
throw new ApiError(response.status, response.statusText) throw new ApiError(response.status, response.statusText)
} }

View File

@ -1,9 +1,10 @@
import { useQuery, useQueryClient } from '@tanstack/react-query' import { useQuery, useQueryClient } from '@tanstack/react-query'
import { createFileRoute, useParams } from '@tanstack/react-router' import { createFileRoute, useParams } from '@tanstack/react-router'
import { ApiError } from '../../api/ApiError'
import getImage from '../../api/getImage'
import getRecipe from '../../api/getRecipe' import getRecipe from '../../api/getRecipe'
import { useAuth } from '../../auth' import { useAuth } from '../../auth'
import Recipe from '../../pages/recipe/Recipe' import Recipe from '../../pages/recipe/Recipe'
import getImage from '../../api/getImage'
export const Route = createFileRoute('/recipes/$username/$slug')({ export const Route = createFileRoute('/recipes/$username/$slug')({
component() { component() {
@ -52,7 +53,15 @@ export const Route = createFileRoute('/recipes/$username/$slug')({
if (isLoading || isImageLoading) { if (isLoading || isImageLoading) {
return 'Loading...' return 'Loading...'
} else if (error !== null) { } 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) { } else if (imageError !== null) {
return `Image loading error: ${imageError} ${imageError.message}` return `Image loading error: ${imageError} ${imageError.message}`
} else if (recipe !== undefined && imgUrl !== undefined) { } else if (recipe !== undefined && imgUrl !== undefined) {