diff --git a/package.json b/package.json
index 043f07c..40feb01 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"next": "13.1.6",
"react": "18.2.0",
"react-dom": "18.2.0",
+ "react-toastify": "^9.1.1",
"swr": "^2.0.3",
"yup": "^1.0.0"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6d3cc25..56147d9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -22,6 +22,7 @@ specifiers:
prettier: 2.8.4
react: 18.2.0
react-dom: 18.2.0
+ react-toastify: ^9.1.1
swr: ^2.0.3
typescript: ^4.9.5
yup: ^1.0.0
@@ -39,6 +40,7 @@ dependencies:
next: 13.1.6_biqbaboplfbrettd7655fr4n2y
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
yup: 1.0.0
@@ -2638,6 +2640,17 @@ packages:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
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:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies:
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 3cd4df4..30cbcba 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -4,6 +4,8 @@ import CssBaseline from '@mui/material/CssBaseline'
import NextLink, { type LinkProps as NextLinkProps } from 'next/link'
import { LinkProps } from '@mui/material/Link'
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/400.css'
import '@fontsource/roboto/500.css'
@@ -35,6 +37,15 @@ export default function App({ Component, pageProps }: AppProps) {
+
)
}
diff --git a/src/utils/axios.ts b/src/utils/axios.ts
index be6639c..f65d575 100644
--- a/src/utils/axios.ts
+++ b/src/utils/axios.ts
@@ -2,6 +2,19 @@ import axios, { type AxiosError } from 'axios'
import Router from 'next/router'
import status from 'http-status'
import * as api from '@/api'
+import { toast } from 'react-toastify'
+
+interface ErrorResponse {
+ statusCode: number
+ message: string
+}
+
+const throwError = (error: AxiosError) => {
+ toast.error(
+ error.response?.data.message.toString() ?? error.response?.statusText,
+ )
+ return Promise.reject(error)
+}
axios.interceptors.request.use(function (config) {
const accessToken = localStorage.getItem('accessToken')
@@ -13,7 +26,7 @@ axios.interceptors.response.use(
function (response) {
return response
},
- async function (error: AxiosError) {
+ async function (error: AxiosError) {
// fail to refresh token
if (
error.config &&
@@ -21,7 +34,7 @@ axios.interceptors.response.use(
error.config.method === 'put'
) {
Router.push('/login')
- return Promise.reject(error)
+ return throwError(error)
}
switch (error.response?.status) {
case status.UNAUTHORIZED: {
@@ -36,7 +49,7 @@ axios.interceptors.response.use(
return error.config && axios.request(error.config)
}
default: {
- return Promise.reject(error)
+ return throwError(error)
}
}
},