Skip to content

Commit

Permalink
Try handling 401s
Browse files Browse the repository at this point in the history
  • Loading branch information
akmatoff committed Apr 28, 2024
1 parent 2ddfb4e commit 7fa7e31
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 77 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
15 changes: 0 additions & 15 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Toaster />
Expand Down
17 changes: 16 additions & 1 deletion src/queries/userdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<IUserData>({
const { data, isFetching, isSuccess, isError, error } = useQuery<IUserData>({
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,
Expand Down
79 changes: 18 additions & 61 deletions src/requests/request.ts
Original file line number Diff line number Diff line change
@@ -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);
}
);
28 changes: 28 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit 7fa7e31

Please sign in to comment.