Skip to content

Commit

Permalink
Handle validation error from commerce-sdk-isomorphic (#718)
Browse files Browse the repository at this point in the history
* 1st attempt at disabling retry when seeing validation error

* Make sure the retries would stop

* Add todos

* Add comment

* Some refactoring and typing

* Remove some guards

* Add comments

* Remove comments

* Demonstrate user error

* React Query's retries are now done only for 5xx server errors

* For easier debugging

* Revert change

Since we plan to remove the QueryClientProvider in our commerce hooks. See PR #734

* Disable retries

And set the option at the individual query level.

* Revert adding query options on individual queries

* Remove todo

We can't use ResponseError yet, since it's not exported by the isomorphic sdk.

* Create a new page to see the errors

* Test validation error
  • Loading branch information
vmarta authored Oct 4, 2022
1 parent 936ea30 commit eb0c06c
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ const CategoryComponent = ({id}: {id: string}): ReactElement => {
</div>
)
}

const IncorrectArguments = (): ReactElement => {
// @ts-ignore
const {isLoading, error} = useProducts({FOO: ''})

return (
<div>
{isLoading && <span>Loading...</span>}
{error && <span>error</span>}
</div>
)
}

const tests = [
{
hook: 'useProducts',
Expand Down Expand Up @@ -117,6 +130,15 @@ const tests = [
expect(screen.getByText('error')).toBeInTheDocument()
expect(screen.queryByText('Loading...')).toBeNull()
})
},
{
name: 'returns validation error',
assertions: async () => {
renderWithProviders(<IncorrectArguments />)
await waitFor(() => screen.getByText('error'))
expect(screen.getByText('error')).toBeInTheDocument()
expect(screen.queryByText('Loading...')).toBeNull()
}
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ function useProducts(
arg: UseProductsArg,
options?: UseQueryOptions<DataType<Client['getProducts']> | Response, Error>
) {
if (!arg.ids) {
throw new Error('ids is required for useProducts')
}
const {headers, rawResponse, ...parameters} = arg
return useAsync(
['products', arg],
Expand Down Expand Up @@ -67,9 +64,6 @@ function useProduct(
arg: UseProductArg,
options?: UseQueryOptions<DataType<Client['getProduct']> | Response, Error>
): UseQueryResult<DataType<Client['getProduct']> | Response, Error> {
if (!arg.id) {
throw new Error('id is required for useProduct.')
}
const {headers, rawResponse, ...parameters} = arg
return useAsync(
['product', arg],
Expand Down Expand Up @@ -105,9 +99,6 @@ function useCategories(
arg: UseCategoriesArg,
options?: UseQueryOptions<DataType<Client['getCategories']> | Response, Error>
): UseQueryResult<DataType<Client['getCategories']> | Response, Error> {
if (!arg.ids) {
throw new Error('ids is required for useCategories')
}
const {headers, rawResponse, ...parameters} = arg
return useAsync(
['categories', arg],
Expand Down
5 changes: 4 additions & 1 deletion packages/commerce-sdk-react/src/test-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export const TEST_CONFIG = {
currency: 'USD'
}
const TestProviders = (props: {children: React.ReactNode}) => {
const queryClient = new QueryClient()
const queryClient = new QueryClient({
// During testing, we want things to fail immediately
defaultOptions: {queries: {retry: false}, mutations: {retry: false}}
})

return (
<QueryClientProvider client={queryClient}>
Expand Down
8 changes: 8 additions & 0 deletions packages/test-commerce-sdk-react/app/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const Home = () => {
demostrate the feature.
</p>
<p>Happy coding.</p>

<h2>Hooks</h2>
<ul>
<li>
Expand All @@ -36,6 +37,13 @@ const Home = () => {
<Link to="/slas-helpers">useShopperLoginHelper</Link>
</li>
</ul>

<h2>Miscellaneous</h2>
<ul>
<li>
<Link to="/query-errors">Query errors</Link>
</li>
</ul>
</>
)
}
Expand Down
71 changes: 71 additions & 0 deletions packages/test-commerce-sdk-react/app/pages/query-errors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2022, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import React from 'react'
import {useProducts, useProduct} from 'commerce-sdk-react'
import Json from '../components/Json'

const QueryErrors = () => {
// @ts-ignore
const products = useProducts({FOO: ''})
const product = useProduct({id: '25502228Mxxx'})

return (
<>
<h1>Query Errors</h1>

<p>
Two common errors you&apos;ll find when using the{' '}
<code>commerce-sdk-isomorphic</code> library are:
</p>
<ul>
<li>
<strong>Validation error</strong> (e.g. when you pass in the wrong arguments to
the function call)
</li>
<li>
<strong>Response error</strong> (e.g. 4xx and 5xx http errors from the
underlying Commerce API)
</li>
</ul>

<h2>Validation Error</h2>
{products.isLoading && <p style={{background: 'aqua'}}>Loading...</p>}
{products.error && <p style={{color: 'red'}}>Something is wrong</p>}

<div>
<div>Returning data</div>
<Json
data={{
isLoading: products.isLoading,
error: products.error,
data: products.data
}}
/>
</div>

<h2>Response Error</h2>
{product.isLoading && <p style={{background: 'aqua'}}>Loading...</p>}
{product.error && <p style={{color: 'red'}}>Something is wrong</p>}

<div>
<div>Returning data</div>
<Json
data={{
isLoading: product.isLoading,
error: product.error,
data: product.data
}}
/>
</div>
</>
)
}

QueryErrors.getTemplateName = () => 'QueryErrors'

export default QueryErrors
5 changes: 5 additions & 0 deletions packages/test-commerce-sdk-react/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const UseCategories = loadable(() => import('./pages/use-shopper-categories'))
const UseCategory = loadable(() => import('./pages/use-shopper-category'))
const UseProductSearch = loadable(() => import('./pages/use-product-search'))
const UseShopperLoginHelper = loadable(() => import('./pages/use-shopper-login-helper'))
const QueryErrors = loadable(() => import('./pages/query-errors'))

const routes = [
{
Expand Down Expand Up @@ -48,6 +49,10 @@ const routes = [
{
path: '/slas-helpers',
component: UseShopperLoginHelper
},
{
path: '/query-errors',
component: QueryErrors
}
]

Expand Down

0 comments on commit eb0c06c

Please sign in to comment.