From 576392ba5f22d0f38b8be53c4449741afe0661ba Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sun, 7 Nov 2021 17:24:10 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20improve=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ frontend/src/features/register/Register.tsx | 16 +++++++++++++--- .../src/features/register/createOrder.graphql | 4 ++-- frontend/src/types.ts | 3 ++- main/api/mutations.py | 8 +++++++- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 480ba4b..aaf5f74 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ Before starting, make sure you have a working python and nodejs setup with pyenv poetry shell python manage.py migrate python manage.py runserver + + # in another terminal + cd frontend + npm install + npm start ``` ## References: diff --git a/frontend/src/features/register/Register.tsx b/frontend/src/features/register/Register.tsx index 6d77bd2..3e96053 100644 --- a/frontend/src/features/register/Register.tsx +++ b/frontend/src/features/register/Register.tsx @@ -29,7 +29,7 @@ export const Register: React.FC = () => { const [selectedUser, setSelectedUser] = useState(""); const [order, setOrder] = useState([]); const [createOrderMutation, { loading: mutateLoading }] = useMutation(CreateOrderDocument, { - variables: { customerId: selectedUser, orderLines: order }, + variables: { customerId: selectedUser, isExternal: selectedUser === USER_EXTERNAL, orderLines: order }, }); const { showToast } = useToast(); @@ -70,11 +70,21 @@ export const Register: React.FC = () => { return; } const { data } = res; - if (data?.createOrder?.__typename === "CreateOrderSuccess") { + const createOrderResponse = data?.createOrder; + if (createOrderResponse?.__typename === "CreateOrderSuccess") { showToast("Woop"); + reset(); return; } - showToast("booo"); + + if (createOrderResponse?.__typename === "FormErrors") { + showToast(createOrderResponse.message); + return; + } + + if (createOrderResponse?.__typename === "InsufficientFunds") { + showToast(`${createOrderResponse.message} Du mangler ${createOrderResponse.amountLacking},-`); + } }; return (
diff --git a/frontend/src/features/register/createOrder.graphql b/frontend/src/features/register/createOrder.graphql index 0211f9c..317a185 100644 --- a/frontend/src/features/register/createOrder.graphql +++ b/frontend/src/features/register/createOrder.graphql @@ -1,5 +1,5 @@ -mutation CreateOrder($customerId: ID!, $orderLines:[OrderLineInput!]!) { - createOrder(customerId: $customerId, orderLines: $orderLines) { +mutation CreateOrder($customerId: ID!, $orderLines:[OrderLineInput!]!, $isExternal: Boolean) { + createOrder(customerId: $customerId, orderLines: $orderLines, isExternal: $isExternal) { ... on CreateOrderSuccess { order { id diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 5bf384e..fc1df12 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -129,6 +129,7 @@ export type AllUsersQuery = { __typename?: 'Query', allUsers: Array<{ __typename export type CreateOrderMutationVariables = Exact<{ customerId: Scalars['ID']; orderLines: Array | OrderLineInput; + isExternal?: Maybe; }>; @@ -137,4 +138,4 @@ export type CreateOrderMutation = { __typename?: 'Mutation', createOrder: { __ty export const AllProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allProducts"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"active"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allProducts"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"active"},"value":{"kind":"Variable","name":{"kind":"Name","value":"active"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceExt"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceInt"}}]}}]}}]} as unknown as DocumentNode; export const AllUsersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allUsers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allUsers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"lastPurchaseDate"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderLineInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"customerId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}}},{"kind":"Argument","name":{"kind":"Name","value":"orderLines"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOrderSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderSum"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InsufficientFunds"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"amountLacking"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FormErrors"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderLineInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isExternal"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"customerId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}}},{"kind":"Argument","name":{"kind":"Name","value":"orderLines"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}}},{"kind":"Argument","name":{"kind":"Name","value":"isExternal"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isExternal"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOrderSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderSum"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InsufficientFunds"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"amountLacking"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FormErrors"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/main/api/mutations.py b/main/api/mutations.py index b76a1fa..0a98fa4 100644 --- a/main/api/mutations.py +++ b/main/api/mutations.py @@ -45,6 +45,12 @@ def create_order(customer_id: ID, order_lines: list[OrderLineInput], is_external message=message, fields=[FieldError(field="customer_id", message=message)], ) + if not order_lines: + message = "Du har ikke valgt hva du skal kjøpe." + return FormErrors( + message=message, + fields=[FieldError(field="order_lines", message=message)], + ) ols = [] order_sum = 0 @@ -55,7 +61,7 @@ def create_order(customer_id: ID, order_lines: list[OrderLineInput], is_external order_sum += ol.amount * price if not is_external and customer.profile.balance <= order_sum: - return InsufficientFunds(amount_lacking=abs(order_sum - customer.profile.balance)) + return InsufficientFunds(message='Du har ikke nok penger på bok.', amount_lacking=abs(order_sum - customer.profile.balance)) # create order = models.Order.objects.create(customer=customer, order_sum=order_sum)