From 7fa7e31a6147b5f6b99aed83088f46d82ed307b4 Mon Sep 17 00:00:00 2001 From: akmatoff Date: Mon, 29 Apr 2024 02:10:57 +0600 Subject: [PATCH] Try handling 401s --- package.json | 1 + src/App.tsx | 15 -------- src/queries/userdata.ts | 17 ++++++++- src/requests/request.ts | 79 ++++++++++------------------------------- yarn.lock | 28 +++++++++++++++ 5 files changed, 63 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index 8d32992..2163325 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview --port 4000" }, "dependencies": { + "@dnd-kit/core": "^6.1.0", "@hookform/resolvers": "^3.3.4", "@tanstack/react-query": "^5.17.19", "@tiptap/extension-code-block-lowlight": "^2.2.0", diff --git a/src/App.tsx b/src/App.tsx index ca7e88d..0b8b1a9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,21 +1,6 @@ import { Toaster } from "react-hot-toast"; -import { cleanInterceptors, setInterceptors } from "./requests/request"; -import { useEffect } from "react"; -import { useNavigate } from "react-router-dom"; -import { useNotification } from "./hooks/useNotification"; function App() { - const navigate = useNavigate(); - const { showErrorNotification } = useNotification(); - - useEffect(() => { - setInterceptors({ navigate, showNotification: showErrorNotification }); - - return () => { - cleanInterceptors(); - }; - }, [navigate, showErrorNotification]); - return ( <> diff --git a/src/queries/userdata.ts b/src/queries/userdata.ts index 6409d57..819de52 100644 --- a/src/queries/userdata.ts +++ b/src/queries/userdata.ts @@ -2,13 +2,28 @@ import { IUserData } from "../interfaces/auth"; import { useQuery } from "@tanstack/react-query"; import { QUERY_KEYS } from "../constants/queryKeys"; import getUserData from "../requests/auth/getUserData"; +import { useEffect } from "react"; +import { useNotification } from "@/hooks/useNotification"; +import { useNavigate } from "react-router-dom"; +import { ROUTES } from "@/constants/routes"; export const useUserData = () => { - const { data, isFetching, isSuccess, isError } = useQuery({ + const { data, isFetching, isSuccess, isError, error } = useQuery({ queryKey: [QUERY_KEYS.USERDATA], queryFn: getUserData, }); + const { showErrorNotification } = useNotification(); + const navigate = useNavigate(); + + useEffect(() => { + // @ts-expect-error wrong interface for the error, it has the response object + if (isError && error.status === 401) { + showErrorNotification("Пожалуйста авторизуйтесь"); + navigate(ROUTES.LOGIN); + } + }, [isError, showErrorNotification, navigate, error]); + return { data, isFetching, diff --git a/src/requests/request.ts b/src/requests/request.ts index ce087c0..f986964 100644 --- a/src/requests/request.ts +++ b/src/requests/request.ts @@ -1,72 +1,29 @@ import axios from "axios"; -import { NavigateFunction } from "react-router-dom"; import { StorageKeys } from "../constants/storageKeys"; -import { ROUTES } from "@/constants/routes"; - -interface InterceptorParams { - navigate?: NavigateFunction; - showNotification?: (message: string) => void; -} - -export class ApiError extends Error { - statusCode; - - constructor(message: string, statusCode?: number) { - super(message); - this.statusCode = statusCode; - } -} export const request = axios.create({ baseURL: import.meta.env.VITE_BASE_URL || "", }); -export const requestInterceptor = () => - request.interceptors.request.use((config) => { - const token = localStorage.getItem(StorageKeys.TOKEN); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - - return config; - }); - -export const responseInterceptor = ({ - navigate, - showNotification, -}: InterceptorParams) => - request.interceptors.response.use( - (response) => response, - (error) => { - if (error.response.status === 403) { - showNotification?.("Нет доступа к ресурсу"); - - throw new ApiError("Нет доступа к ресурсу", 403); - } else if ( - error.response.status === 401 && - !error.request.responseURL.includes("login") - ) { - localStorage.removeItem(StorageKeys.TOKEN); - - navigate?.(ROUTES.LOGIN); - showNotification?.("Пожалуйста авторизуйтесь"); +request.interceptors.request.use((config) => { + const token = localStorage.getItem(StorageKeys.TOKEN); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } - throw new ApiError("Пожалуйста авторизуйтесь", 401); - } + return config; +}); - return Promise.reject(error.response || error.message); +request.interceptors.response.use( + (response) => response, + (error) => { + if ( + error.response.status === 401 && + !error.request.responseURL.includes("login") + ) { + localStorage.removeItem(StorageKeys.TOKEN); } - ); - -export const setInterceptors = ({ - navigate, - showNotification, -}: InterceptorParams) => { - requestInterceptor(); - responseInterceptor({ navigate, showNotification }); -}; -export const cleanInterceptors = () => { - request.interceptors.request.eject(requestInterceptor()); - request.interceptors.response.eject(responseInterceptor({})); -}; + return Promise.reject(error.response || error.message); + } +); diff --git a/yarn.lock b/yarn.lock index b8fd891..cd0e1cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -220,6 +220,29 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@dnd-kit/accessibility@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz#1054e19be276b5f1154ced7947fc0cb5d99192e0" + integrity sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ== + dependencies: + tslib "^2.0.0" + +"@dnd-kit/core@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@dnd-kit/core/-/core-6.1.0.tgz#e81a3d10d9eca5d3b01cbf054171273a3fe01def" + integrity sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg== + dependencies: + "@dnd-kit/accessibility" "^3.1.0" + "@dnd-kit/utilities" "^3.2.2" + tslib "^2.0.0" + +"@dnd-kit/utilities@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@dnd-kit/utilities/-/utilities-3.2.2.tgz#5a32b6af356dc5f74d61b37d6f7129a4040ced7b" + integrity sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg== + dependencies: + tslib "^2.0.0" + "@esbuild/aix-ppc64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" @@ -2558,6 +2581,11 @@ tsconfck@^3.0.1: resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.0.1.tgz#803ca0ed8f2f2075639e4061238f04b99ba85e85" integrity sha512-7ppiBlF3UEddCLeI1JRx5m2Ryq+xk4JrZuq4EuYXykipebaq1dV0Fhgr1hb7CkmHt32QSgOZlcqVLEtHBG4/mg== +tslib@^2.0.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"