handle axios error

This commit is contained in:
秦秋旭 2023-02-20 23:49:26 +08:00
parent b95a99aaff
commit c7f973e27a
4 changed files with 41 additions and 3 deletions

View File

@ -23,6 +23,7 @@
"next": "13.1.6", "next": "13.1.6",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-toastify": "^9.1.1",
"swr": "^2.0.3", "swr": "^2.0.3",
"yup": "^1.0.0" "yup": "^1.0.0"
}, },

View File

@ -22,6 +22,7 @@ specifiers:
prettier: 2.8.4 prettier: 2.8.4
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0 react-dom: 18.2.0
react-toastify: ^9.1.1
swr: ^2.0.3 swr: ^2.0.3
typescript: ^4.9.5 typescript: ^4.9.5
yup: ^1.0.0 yup: ^1.0.0
@ -39,6 +40,7 @@ dependencies:
next: 13.1.6_biqbaboplfbrettd7655fr4n2y next: 13.1.6_biqbaboplfbrettd7655fr4n2y
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
react-toastify: 9.1.1_biqbaboplfbrettd7655fr4n2y
swr: 2.0.3_react@18.2.0 swr: 2.0.3_react@18.2.0
yup: 1.0.0 yup: 1.0.0
@ -2638,6 +2640,17 @@ packages:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: false dev: false
/react-toastify/9.1.1_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-pkFCla1z3ve045qvjEmn2xOJOy4ZciwRXm1oMPULVkELi5aJdHCN/FHnuqXq8IwGDLB7PPk2/J6uP9D8ejuiRw==}
peerDependencies:
react: '>=16'
react-dom: '>=16'
dependencies:
clsx: 1.2.1
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
dev: false
/react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y: /react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies: peerDependencies:

View File

@ -4,6 +4,8 @@ import CssBaseline from '@mui/material/CssBaseline'
import NextLink, { type LinkProps as NextLinkProps } from 'next/link' import NextLink, { type LinkProps as NextLinkProps } from 'next/link'
import { LinkProps } from '@mui/material/Link' import { LinkProps } from '@mui/material/Link'
import { ThemeProvider, createTheme } from '@mui/material' import { ThemeProvider, createTheme } from '@mui/material'
import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
import '@fontsource/roboto/300.css' import '@fontsource/roboto/300.css'
import '@fontsource/roboto/400.css' import '@fontsource/roboto/400.css'
import '@fontsource/roboto/500.css' import '@fontsource/roboto/500.css'
@ -35,6 +37,15 @@ export default function App({ Component, pageProps }: AppProps) {
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<Component {...pageProps} /> <Component {...pageProps} />
<ToastContainer
position="top-center"
autoClose={3000}
hideProgressBar
newestOnTop={false}
closeOnClick
pauseOnFocusLoss={false}
pauseOnHover
/>
</ThemeProvider> </ThemeProvider>
) )
} }

View File

@ -2,6 +2,19 @@ import axios, { type AxiosError } from 'axios'
import Router from 'next/router' import Router from 'next/router'
import status from 'http-status' import status from 'http-status'
import * as api from '@/api' import * as api from '@/api'
import { toast } from 'react-toastify'
interface ErrorResponse {
statusCode: number
message: string
}
const throwError = (error: AxiosError<ErrorResponse>) => {
toast.error(
error.response?.data.message.toString() ?? error.response?.statusText,
)
return Promise.reject(error)
}
axios.interceptors.request.use(function (config) { axios.interceptors.request.use(function (config) {
const accessToken = localStorage.getItem('accessToken') const accessToken = localStorage.getItem('accessToken')
@ -13,7 +26,7 @@ axios.interceptors.response.use(
function (response) { function (response) {
return response return response
}, },
async function (error: AxiosError) { async function (error: AxiosError<ErrorResponse>) {
// fail to refresh token // fail to refresh token
if ( if (
error.config && error.config &&
@ -21,7 +34,7 @@ axios.interceptors.response.use(
error.config.method === 'put' error.config.method === 'put'
) { ) {
Router.push('/login') Router.push('/login')
return Promise.reject(error) return throwError(error)
} }
switch (error.response?.status) { switch (error.response?.status) {
case status.UNAUTHORIZED: { case status.UNAUTHORIZED: {
@ -36,7 +49,7 @@ axios.interceptors.response.use(
return error.config && axios.request(error.config) return error.config && axios.request(error.config)
} }
default: { default: {
return Promise.reject(error) return throwError(error)
} }
} }
}, },