Skip to content

Commit 4df2ce5

Browse files
committed
Merge branch 'dev' of https://github.com/martis-git/github-client into dev
2 parents 05866fb + ba00eda commit 4df2ce5

File tree

10 files changed

+59
-26
lines changed

10 files changed

+59
-26
lines changed

src/app/error-handling/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/app/hocs/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ import withAntd from "./with-antd";
1111
* - логику инициализации роутера (withRouter)
1212
*/
1313
export const withHocs = compose(withAntd, withRouter, withApollo);
14+
15+
export { ErrorHandlingProvider } from "./with-error-handling";
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React, { lazy } from "react";
2+
import { alert } from "shared/helpers";
3+
import { Error } from "features";
4+
import { AppError } from "models";
5+
6+
const ErrorPage = lazy(() => import("pages/error"));
7+
8+
/**
9+
* @hoc Инициализация отлова ошибок
10+
*/
11+
export const ErrorHandlingProvider = ({ children }: PropsWithChildren) => {
12+
const onNetworkError = ({ message, description }: AppError) => alert.warn(message, description);
13+
return (
14+
<Error.Catcher
15+
onNetworkError={onNetworkError}
16+
handler={({ error }) => <ErrorPage error={error} />}
17+
>
18+
{children}
19+
</Error.Catcher>
20+
);
21+
};

src/app/index.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import React, { lazy } from "react";
1+
import React from "react";
22
import { Layout } from "antd";
33
import Routing from "pages";
4-
import { ErrorCatcher } from "./error-handling";
54
import Header from "./header";
6-
import { withHocs } from "./hocs";
5+
import { withHocs, ErrorHandlingProvider } from "./hocs";
76
import "./index.scss";
87

9-
// !!! FIXME: manage access
10-
const ErrorPage = lazy(() => import("pages/error"));
11-
128
/**
139
* Entry-point приложения
1410
* @remark Содержит в HOC-обертке инициализирующую логику приложения
@@ -20,9 +16,9 @@ const App = () => {
2016
<Layout>
2117
<Header />
2218
<Layout.Content className="gc-app-content">
23-
<ErrorCatcher handler={({ error }) => <ErrorPage error={error} />}>
19+
<ErrorHandlingProvider>
2420
<Routing />
25-
</ErrorCatcher>
21+
</ErrorHandlingProvider>
2622
</Layout.Content>
2723
</Layout>
2824
</div>
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import { onError } from "@apollo/client/link/error";
33
import { useApolloClient } from "@apollo/client";
44
import { useLocation } from "react-router";
55
import { AppError } from "models";
6+
import { Definitions } from "./definitions";
67
import { mapError } from "./helpers";
78

89
type Props = PropsWithChildren<{
910
/** Отрисовщик-обработчик ошибки */
1011
handler: (props: { error: AppError }) => ReactNode;
12+
onNetworkError?: (error: AppError) => void;
1113
}>;
1214

1315
/**
@@ -19,7 +21,8 @@ const useAppError = () => {
1921

2022
useEffect(() => {
2123
const errorLink = onError(({ graphQLErrors, networkError }) => {
22-
setError(mapError(graphQLErrors?.[0] || networkError));
24+
const appError = mapError(graphQLErrors?.[0] || networkError);
25+
setError(appError || null);
2326
});
2427
apolloClient.setLink(errorLink.concat(apolloClient.link));
2528
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -29,19 +32,23 @@ const useAppError = () => {
2932
};
3033

3134
/**
32-
* Обертка для обработки ошибок
35+
* @feature Обертка для обработки ошибок
3336
* FIXME: add ErrorBoundaries
3437
*/
35-
const ErrorCatcher = ({ handler, children }: Props) => {
38+
const Catcher = ({ handler, children, onNetworkError }: Props) => {
3639
const location = useLocation();
3740
const { error, setError } = useAppError();
3841

3942
useEffect(() => setError(null), [location, setError]);
43+
useEffect(() => {
44+
if (error?.code !== Definitions.NETWORK_ERROR.code) return;
45+
onNetworkError?.(error);
46+
}, [error, onNetworkError]);
4047

41-
if (error) {
48+
if (error && error.code !== Definitions.NETWORK_ERROR.code) {
4249
return <>{handler({ error })}</>;
4350
}
4451
return <>{children}</>;
4552
};
4653

47-
export default ErrorCatcher;
54+
export default Catcher;

src/app/error-handling/error-definitions.ts renamed to src/features/error/definitions.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AppError } from "models";
33
/**
44
* Обрабатываемые ошибки приложения
55
*/
6-
export const ErrorDefinitions: Record<string, AppError> = {
6+
export const Definitions: Record<string, AppError> = {
77
UNAUTHORIZED: {
88
code: 401,
99
message: "You shall not pass!",
@@ -24,4 +24,9 @@ export const ErrorDefinitions: Record<string, AppError> = {
2424
message: "500 Server Error\nSomething’s wrong!",
2525
description: "we’re doing smth",
2626
},
27+
NETWORK_ERROR: {
28+
code: -1,
29+
message: "Check your connection",
30+
description: "Failed to make a request",
31+
},
2732
};
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ServerError } from "@apollo/client";
22
import { GraphQLError } from "graphql";
33
import { AppError } from "models";
4-
import { ErrorDefinitions } from "./error-definitions";
4+
import { Definitions } from "./definitions";
55

66
/**
77
* Проверка: является ли ошибка GitHub Error
@@ -26,12 +26,15 @@ export function mapError(error?: GraphQLError | Error | ServerError): AppError |
2626
if (isGithubError(error)) {
2727
// FIXME: handle 403 and 500 errors as well w/o side effects
2828
if (error.type === "NOT_FOUND") {
29-
return ErrorDefinitions[error.type];
29+
return Definitions[error.type];
3030
}
3131
}
3232
if (isServerError(error)) {
33-
if (error.statusCode === 401) return ErrorDefinitions.UNAUTHORIZED;
33+
if (error.statusCode === 401) return Definitions.UNAUTHORIZED;
3434
}
35-
// TODO: handle network errors and whatever can be broken
35+
if (error instanceof TypeError && error.message === "Failed to fetch") {
36+
return Definitions.NETWORK_ERROR;
37+
}
38+
// TODO: handle other errors and whatever can be broken
3639
return null;
3740
}

src/features/error/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as Catcher } from "./catcher";
2+
export * from "./definitions";

src/features/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Импортим отдельно, т.к. фича экспортит из себя много подмодулей
22
import * as Auth from "./auth";
3+
import * as Error from "./error";
34

45
// FIXME: Нормализовать экспорты к единому виду
56

@@ -12,3 +13,4 @@ export { default as Search } from "./search";
1213
export { default as Origin } from "./origin";
1314
export { default as HeroSheet } from "./hero-sheet";
1415
export { Auth };
16+
export { Error };

src/pages/error/index.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import React from "react";
2-
// !!! FIXME: это плохо(
3-
// eslint-disable-next-line import/order
4-
import { ErrorDefinitions } from "app/error-handling";
5-
import { Auth, HeroSheet } from "features";
2+
import { Auth, Error, HeroSheet } from "features";
63
import { AppError } from "models";
74
import { useTitle } from "../helpers";
85

@@ -28,7 +25,7 @@ const useAppErrors = (error: AppError) => {
2825
};
2926

3027
const action =
31-
error.code === ErrorDefinitions.UNAUTHORIZED.code ? unauthorizedAction : undefined;
28+
error.code === Error.Definitions.UNAUTHORIZED.code ? unauthorizedAction : undefined;
3229
return { action };
3330
};
3431

@@ -37,7 +34,7 @@ const useAppErrors = (error: AppError) => {
3734
* @remark Отображается при возникающих ошибках в приложении
3835
*/
3936
const ErrorPage = ({ error }: Props) => {
40-
useTitle(`Error occured · ${error.code || "Unknown"}`);
37+
useTitle(`Error occurred · ${error.code || "Unknown"}`);
4138
const { action } = useAppErrors(error);
4239

4340
return (

0 commit comments

Comments
 (0)