Skip to content

Commit 7eaad76

Browse files
authored
Merge pull request #155 from niyazm524/feature/auth-errors
Обработка ошибок авторизации
2 parents b54398a + f2ac2a8 commit 7eaad76

File tree

7 files changed

+51
-17
lines changed

7 files changed

+51
-17
lines changed

src/app/error-handling/error-catcher.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useState, ReactNode } from "react";
2-
import { useApolloClient } from "@apollo/client";
2+
import { ServerError, useApolloClient } from "@apollo/client";
33
import { onError } from "@apollo/client/link/error";
44
import { GraphQLError } from "graphql";
55
import { useLocation } from "react-router";
@@ -10,14 +10,21 @@ const isGithubError = (error: any): error is { type: string } => {
1010
return typeof error.type === "string";
1111
};
1212

13-
function mapError(error: GraphQLError | Error | undefined): AppError | null {
13+
const isServerError = (error: any): error is ServerError => {
14+
return typeof error.statusCode === "number";
15+
};
16+
17+
function mapError(error: GraphQLError | Error | ServerError | undefined): AppError | null {
1418
if (!error) return null;
1519
if (isGithubError(error)) {
1620
// FIXME: handle 403 and 500 errors as well w/o side effects
1721
if (error.type === "NOT_FOUND") {
1822
return ErrorDefinitions[error.type];
1923
}
2024
}
25+
if (isServerError(error)) {
26+
if (error.statusCode === 401) return ErrorDefinitions.UNAUTHORIZED;
27+
}
2128
// TODO: handle network errors and whatever can be broken
2229
return null;
2330
}

src/app/error-handling/error-definitions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { AppError } from "models";
22

33
export const ErrorDefinitions: Record<string, AppError> = {
4+
UNAUTHORIZED: {
5+
code: 401,
6+
message: "You shall not pass!",
7+
description: "Occurred problems with your credential. Re-sign in, please",
8+
},
49
FORBIDDEN: {
510
code: 403,
611
message: "Yo, access Forbidden\nYou shouldn’t be here",

src/app/error-handling/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as ErrorCatcher } from "./error-catcher";
2+
export { ErrorDefinitions } from "./error-definitions";

src/features/auth/page/index.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
2-
import { Alert, Card } from "antd";
32
import { GithubFilled } from "@ant-design/icons";
3+
import { Alert, Card, notification } from "antd";
44
// !!! FIXME: loop imports
55
import { useTitle } from "pages/helpers";
66
import { authorizeGithub } from "../firebase";
@@ -21,9 +21,14 @@ import "./index.scss";
2121
const AuthPage = () => {
2222
useTitle("Sign in to Github Client");
2323
const { login } = useAuth();
24+
const showError = (message: string) =>
25+
notification.error({ message: "Authorization error", description: message, top: 72 });
26+
27+
// TODO: add ability to specify redirect url
2428
const authorize = () => {
25-
authorizeGithub().then(login);
26-
// TODO: add catch handling!
29+
authorizeGithub()
30+
.then(login)
31+
.catch((err: Error) => showError(err.message));
2732
};
2833

2934
return (

src/features/home-hero/index.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import { Col, Row } from "antd";
22
import React from "react";
3+
import { useHistory } from "react-router-dom";
34
import { ReactComponent as Icon } from "./assets/github-icon.svg";
45
import { ReactComponent as SadIcon } from "./assets/github-icon-sad.svg";
56
import "./index.scss";
67

78
type Props = {
89
title: string;
910
description: string;
10-
action: { text: string; to: () => void };
11+
action?: { text: string; to: () => void };
1112
useSadHero?: boolean;
1213
};
1314

1415
const HomeHero = ({ title, description, action, useSadHero = false }: Props) => {
16+
const history = useHistory();
17+
const preferredAction = action ?? {
18+
text: "Back",
19+
to: () => (history.length > 1 ? history.goBack() : history.push("/")),
20+
};
21+
1522
return (
1623
<div className="page page-background">
1724
<Row className="home-hero">
1825
<Col span={16}>
1926
<h1 className="home-hero__title">{title}</h1>
2027
<p className="home-hero__description">{description}</p>
21-
<button className="home-hero__button" onClick={() => action.to()}>
22-
{action.text}
28+
<button className="home-hero__button" onClick={() => preferredAction.to()}>
29+
{preferredAction.text}
2330
</button>
2431
</Col>
2532
<Col span={8}>

src/pages/error/index.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
import React from "react";
2-
import { useHistory } from "react-router";
3-
import HomeHero from "../../features/home-hero";
4-
import { AppError } from "../../models";
2+
import { ErrorDefinitions } from "app/error-handling";
3+
import { Auth } from "features";
4+
import HomeHero from "features/home-hero";
5+
import { AppError } from "models";
56

67
type Props = { error: AppError };
78

89
export default function ErrorPage({ error }: Props) {
9-
const history = useHistory();
10+
const { logout } = Auth.useAuth();
11+
12+
const action =
13+
error.code === ErrorDefinitions.UNAUTHORIZED.code
14+
? {
15+
text: "Authorize",
16+
to: () => {
17+
logout();
18+
window.location.href = "/auth";
19+
},
20+
}
21+
: undefined;
1022

1123
return (
1224
<HomeHero
1325
title={error.message}
1426
description={error.description}
1527
useSadHero
16-
action={{
17-
text: "Back",
18-
to: () => (history.length > 1 ? history.goBack() : history.push("/")),
19-
}}
28+
action={action}
2029
/>
2130
);
2231
}

src/pages/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Routing = () => {
1818
<Switch>
1919
<Route exact path={Auth.routes.main} component={HomePage} />
2020
<Route exact path={Auth.routes.login} component={Auth.Page} />
21-
<Redirect to={Auth.routes.main} />
21+
<Redirect to={Auth.routes.login} />
2222
</Switch>
2323
);
2424
}

0 commit comments

Comments
 (0)