feat: errors description
This commit is contained in:
parent
17a697893d
commit
01f1e50c4a
@ -18,8 +18,6 @@ import Landing from "./pages/Landing/Landing";
|
|||||||
import Main from "./pages/main";
|
import Main from "./pages/main";
|
||||||
import {
|
import {
|
||||||
clearAuthToken,
|
clearAuthToken,
|
||||||
createUserAccount,
|
|
||||||
devlog,
|
|
||||||
getMessageFromFetchError,
|
getMessageFromFetchError,
|
||||||
UserAccount,
|
UserAccount,
|
||||||
useUserFetcher,
|
useUserFetcher,
|
||||||
|
|||||||
@ -67,7 +67,7 @@ export const logout = async (): Promise<[unknown, string?]> => {
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось выйти. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import {
|
|||||||
import { replaceSpacesToEmptyLines } from "../utils/replaceSpacesToEmptyLines";
|
import { replaceSpacesToEmptyLines } from "../utils/replaceSpacesToEmptyLines";
|
||||||
import { parseAxiosError } from "@utils/parse-error";
|
import { parseAxiosError } from "@utils/parse-error";
|
||||||
|
|
||||||
const API_URL = "/squiz";
|
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
||||||
|
|
||||||
export const createQuestion = async (
|
export const createQuestion = async (
|
||||||
body: CreateQuestionRequest,
|
body: CreateQuestionRequest,
|
||||||
@ -39,7 +39,7 @@ export const createQuestion = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось создать вопрос. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ const getQuestionList = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось получить список вопросов. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ export const editQuestion = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось изменить вопрос. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ export const copyQuestion = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось скопировать вопрос. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ export const deleteQuestion = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось удалить вопрос. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export const createQuiz = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось создать квиз. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export const getQuizList = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось получить список квизов. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ export const getQuiz = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось получить квиз. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ export const editQuiz = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось изменить квиз. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ export const copyQuiz = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось скопировать квиз. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ export const deleteQuiz = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось удалить квиз. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ export const addQuizImages = async (
|
|||||||
} catch (nativeError) {
|
} catch (nativeError) {
|
||||||
const [error] = parseAxiosError(nativeError);
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
return [null, error];
|
return [null, `Не удалось добавить картинку. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -31,12 +31,18 @@ export interface IAnswerResult {
|
|||||||
question_id: number;
|
question_id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResultFilter = {
|
||||||
|
from?: string;
|
||||||
|
new?: boolean;
|
||||||
|
to?: string;
|
||||||
|
};
|
||||||
|
|
||||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
||||||
|
|
||||||
const getResultList = async (
|
const getResultList = async (
|
||||||
quizId: number,
|
quizId: number,
|
||||||
page: number,
|
page: number,
|
||||||
body: any,
|
body: ResultFilter,
|
||||||
): Promise<[RawResult | null, string?]> => {
|
): Promise<[RawResult | null, string?]> => {
|
||||||
try {
|
try {
|
||||||
const resultList = await makeRequest<IResultListBody, RawResult>({
|
const resultList = await makeRequest<IResultListBody, RawResult>({
|
||||||
@ -108,7 +114,7 @@ const getAnswerResultList = async (
|
|||||||
|
|
||||||
const AnswerResultListEx = async (
|
const AnswerResultListEx = async (
|
||||||
quizId: number,
|
quizId: number,
|
||||||
body: any,
|
body: ResultFilter,
|
||||||
): Promise<[unknown | null, string?]> => {
|
): Promise<[unknown | null, string?]> => {
|
||||||
try {
|
try {
|
||||||
const answerResultListEx = await makeRequest<unknown, unknown>({
|
const answerResultListEx = await makeRequest<unknown, unknown>({
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { sendContactFormRequest } from "../api/contactForm";
|
import { sendContactFormRequest } from "../api/contactForm";
|
||||||
import { getMessageFromFetchError } from "../utils/backendMessageHandler";
|
import { parseAxiosError } from "@utils/parse-error";
|
||||||
|
|
||||||
interface ContactFormStore {
|
interface ContactFormStore {
|
||||||
isModalOpen: boolean;
|
isModalOpen: boolean;
|
||||||
@ -72,6 +72,8 @@ export const sendContactForm = async (): Promise<string | null> => {
|
|||||||
return "Данные отправлены";
|
return "Данные отправлены";
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
useContactFormStore.setState({ isSubmitDisabled: false });
|
useContactFormStore.setState({ isSubmitDisabled: false });
|
||||||
return getMessageFromFetchError(error);
|
const [errorMessage] = parseAxiosError(error);
|
||||||
|
|
||||||
|
return errorMessage;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { quizApi } from "@api/quiz";
|
import { quizApi } from "@api/quiz";
|
||||||
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
import { devlog } from "@frontend/kitui";
|
||||||
import { quizToEditQuizRequest } from "@model/quiz/edit";
|
import { quizToEditQuizRequest } from "@model/quiz/edit";
|
||||||
import { Quiz, RawQuiz, rawQuizToQuiz } from "@model/quiz/quiz";
|
import { Quiz, RawQuiz, rawQuizToQuiz } from "@model/quiz/quiz";
|
||||||
import { maxQuizSetupSteps, QuizConfig } from "@model/quizSettings";
|
import { maxQuizSetupSteps, QuizConfig } from "@model/quizSettings";
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { ResultStore, useResultStore } from "@root/results/store";
|
|||||||
import { RawResult, rawResultToResult } from "@model/result/result";
|
import { RawResult, rawResultToResult } from "@model/result/result";
|
||||||
import { RequestQueue } from "@utils/requestQueue";
|
import { RequestQueue } from "@utils/requestQueue";
|
||||||
import { resultApi } from "@api/result";
|
import { resultApi } from "@api/result";
|
||||||
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
import { devlog } from "@frontend/kitui";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import { parseFilters } from "../../pages/QuizAnswersPage/helper";
|
import { parseFilters } from "../../pages/QuizAnswersPage/helper";
|
||||||
|
|||||||
@ -15,12 +15,7 @@ import {
|
|||||||
import { parseAxiosError } from "@utils/parse-error";
|
import { parseAxiosError } from "@utils/parse-error";
|
||||||
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
|
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
|
||||||
import type { Discount } from "@model/discounts";
|
import type { Discount } from "@model/discounts";
|
||||||
import {
|
import { clearAuthToken, createUserAccount, devlog } from "@frontend/kitui";
|
||||||
clearAuthToken,
|
|
||||||
createUserAccount,
|
|
||||||
devlog,
|
|
||||||
getMessageFromFetchError,
|
|
||||||
} from "@frontend/kitui";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { isAxiosError } from "axios";
|
import { isAxiosError } from "axios";
|
||||||
import { activatePromocode } from "@api/promocode";
|
import { activatePromocode } from "@api/promocode";
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import {
|
|||||||
useTicketStore,
|
useTicketStore,
|
||||||
} from "@root/ticket";
|
} from "@root/ticket";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { getMessageFromFetchError } from "@utils/backendMessageHandler";
|
import { parseAxiosError } from "@utils/parse-error";
|
||||||
import { createTicket, sendFile as sendFileRequest } from "@api/ticket";
|
import { createTicket, sendFile as sendFileRequest } from "@api/ticket";
|
||||||
|
|
||||||
type ModalWarningType =
|
type ModalWarningType =
|
||||||
@ -120,7 +120,7 @@ export default () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error: Error) => {
|
onError: (error: Error) => {
|
||||||
const message = getMessageFromFetchError(error);
|
const message = parseAxiosError(error);
|
||||||
if (message) enqueueSnackbar(message);
|
if (message) enqueueSnackbar(message);
|
||||||
},
|
},
|
||||||
onFetchStateChange: () => {},
|
onFetchStateChange: () => {},
|
||||||
@ -137,7 +137,7 @@ export default () => {
|
|||||||
addOrUpdateUnauthMessages(messages);
|
addOrUpdateUnauthMessages(messages);
|
||||||
}, []),
|
}, []),
|
||||||
onError: useCallback((error: Error) => {
|
onError: useCallback((error: Error) => {
|
||||||
const message = getMessageFromFetchError(error);
|
const [message] = parseAxiosError(error);
|
||||||
if (message) enqueueSnackbar(message);
|
if (message) enqueueSnackbar(message);
|
||||||
}, []),
|
}, []),
|
||||||
onFetchStateChange: setUnauthTicketMessageFetchState,
|
onFetchStateChange: setUnauthTicketMessageFetchState,
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
import { isAxiosError } from "axios";
|
|
||||||
|
|
||||||
const backendErrorMessage: Record<string, string> = {
|
|
||||||
"user not found": "Пользователь не найден",
|
|
||||||
"invalid password": "Неправильный пароль",
|
|
||||||
"field <password> is empty": 'Поле "Пароль" не заполнено',
|
|
||||||
"field <login> is empty": 'Поле "Логин" не заполнено',
|
|
||||||
"field <email> is empty": 'Поле "E-mail" не заполнено',
|
|
||||||
"field <phoneNumber> is empty": 'Поле "Номер телефона" не заполнено',
|
|
||||||
"user with this email or login is exist": "Пользователь уже существует",
|
|
||||||
};
|
|
||||||
|
|
||||||
const unknownErrorMessage = "Что-то пошло не так. Повторите попытку позже";
|
|
||||||
|
|
||||||
export function getMessageFromFetchError(error: any): string | null {
|
|
||||||
if (process.env.NODE_ENV !== "production") console.error(error);
|
|
||||||
|
|
||||||
const message = backendErrorMessage[error.response?.data?.message];
|
|
||||||
if (message) return message;
|
|
||||||
|
|
||||||
if (error.message === "Failed to fetch") return "Ошибка сети";
|
|
||||||
|
|
||||||
if (isAxiosError(error)) {
|
|
||||||
switch (error.code) {
|
|
||||||
case "ERR_NETWORK":
|
|
||||||
return "Ошибка сети";
|
|
||||||
case "ERR_CANCELED":
|
|
||||||
return null;
|
|
||||||
case "ERR_BAD_REQUEST":
|
|
||||||
return "Слишком много запросов";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return unknownErrorMessage;
|
|
||||||
}
|
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { isAxiosError } from "axios";
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
|
|
||||||
export type ServerError = {
|
export type ServerError = {
|
||||||
@ -24,6 +25,10 @@ const translateMessage: Record<string, string> = {
|
|||||||
|
|
||||||
export const parseAxiosError = (nativeError: unknown): [string, number?] => {
|
export const parseAxiosError = (nativeError: unknown): [string, number?] => {
|
||||||
const error = nativeError as AxiosError;
|
const error = nativeError as AxiosError;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== "production") console.error(error);
|
||||||
|
if (error.message === "Failed to fetch") return ["Ошибка сети"];
|
||||||
|
|
||||||
if (error.response?.data) {
|
if (error.response?.data) {
|
||||||
const serverError = error.response.data as ServerError;
|
const serverError = error.response.data as ServerError;
|
||||||
let SEMessage;
|
let SEMessage;
|
||||||
@ -41,6 +46,17 @@ export const parseAxiosError = (nativeError: unknown): [string, number?] => {
|
|||||||
return [SEMessage || "", serverError.statusCode];
|
return [SEMessage || "", serverError.statusCode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isAxiosError(error)) {
|
||||||
|
switch (error.code) {
|
||||||
|
case "ERR_NETWORK":
|
||||||
|
return ["Ошибка сети"];
|
||||||
|
case "ERR_CANCELED":
|
||||||
|
return ["Неизвестная ошибка сервера."];
|
||||||
|
case "ERR_BAD_REQUEST":
|
||||||
|
return ["Слишком много запросов"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
case 404:
|
case 404:
|
||||||
return ["Не найдено.", error.status];
|
return ["Не найдено.", error.status];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user