From 95d7d13f38778c0e8c1ee5556fedd440fe6b5684 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sun, 17 Apr 2022 21:13:22 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Handle=20user=20not=20found?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- bbs/api/schema.py | 16 +++++++++++++- frontend/src/components/GQLError.module.css | 9 ++++++++ frontend/src/components/GQLError.tsx | 23 +++++++++++++++++++++ frontend/src/features/users/UserDetail.tsx | 5 ++++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/GQLError.module.css create mode 100644 frontend/src/components/GQLError.tsx diff --git a/.gitignore b/.gitignore index e52fd27..e806e69 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ CACHE/ media/ tmp/ frontend/dist -static/ +static/assets +static/index.html .python-version .env diff --git a/bbs/api/schema.py b/bbs/api/schema.py index 9cb4ed0..4e82213 100644 --- a/bbs/api/schema.py +++ b/bbs/api/schema.py @@ -1,4 +1,6 @@ import strawberry +from django.core.exceptions import ObjectDoesNotExist +from strawberry.extensions import Extension from bbs.api.mutations.shop import ShopMutations from bbs.api.mutations.users import UsersMutations @@ -17,4 +19,16 @@ class Mutation(ShopMutations, UsersMutations): pass -schema = strawberry.Schema(query=Query, mutation=Mutation) +class HandleNotFound(Extension): + def on_request_end(self): + result = self.execution_context.result + if result.errors: + for error in result.errors: + if isinstance(error.original_error, ObjectDoesNotExist): + error.extensions = { + "code": "NOT_FOUND", + "model": type(error.original_error).__qualname__.replace(".DoesNotExist", ""), + } + + +schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[HandleNotFound]) diff --git a/frontend/src/components/GQLError.module.css b/frontend/src/components/GQLError.module.css new file mode 100644 index 0000000..b0995ab --- /dev/null +++ b/frontend/src/components/GQLError.module.css @@ -0,0 +1,9 @@ +.errorMessage { + font-family: Rocket Rinder, monospace; + font-size: 3rem; + font-style: italic; + color: var(--brand); + text-align: center; + width: 100%; + margin-top: 30vh; +} \ No newline at end of file diff --git a/frontend/src/components/GQLError.tsx b/frontend/src/components/GQLError.tsx new file mode 100644 index 0000000..8dc2df3 --- /dev/null +++ b/frontend/src/components/GQLError.tsx @@ -0,0 +1,23 @@ +import { ApolloError } from "@apollo/client"; +import React from "react"; + +import styles from "./GQLError.module.css"; + +const formatModel = (text: string) => { + const withSpaces = text + .replace(/([A-Z])/g, " $1") + .toLocaleLowerCase() + .trim(); + return withSpaces.charAt(0).toUpperCase() + withSpaces.slice(1); +}; + +export const GQLError = ({ error }: { error: ApolloError }) => { + if (error?.graphQLErrors?.length == 1) { + const single = error?.graphQLErrors[0]; + if (single?.extensions?.code === "NOT_FOUND") { + const modelPretty = formatModel(single?.extensions?.model as string); + return
{`${modelPretty} not found`}
; + } + } + return
Error...
; +}; diff --git a/frontend/src/features/users/UserDetail.tsx b/frontend/src/features/users/UserDetail.tsx index 6769fcc..04aae17 100644 --- a/frontend/src/features/users/UserDetail.tsx +++ b/frontend/src/features/users/UserDetail.tsx @@ -3,16 +3,19 @@ import { Line } from "@nivo/line"; import React from "react"; import { useParams } from "react-router-dom"; +import { GQLError } from "../../components/GQLError"; import { User, UserDetailDocument, UserProfile } from "../../types"; import { formatMonth, formatTime } from "../../utils/time"; import styles from "./UserDetail.module.css"; const UserDetail = () => { const { userId } = useParams(); - const { data, loading } = useQuery(UserDetailDocument, { variables: { userId: userId || "" }, skip: !userId }); + const { data, loading, error } = useQuery(UserDetailDocument, { variables: { userId: userId || "" }, skip: !userId }); if (loading) return
Loading...
; + if (error) return ; + const user = data?.user as User; const profile = user?.profile as UserProfile; // FIXME: types