Skip to content

Commit

Permalink
fix(query): handle error in atomWithQuery (#567)
Browse files Browse the repository at this point in the history
* fix(query): handle error

* fix early return

* oops, we need to catch

* hmm, why was this missing

* update size snapshot

* update size snapshot
  • Loading branch information
dai-shi authored Jun 28, 2021
1 parent 6d767a7 commit 5844f7d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
18 changes: 9 additions & 9 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"index.js": {
"bundled": 21126,
"minified": 10113,
"gzipped": 3334,
"bundled": 21254,
"minified": 10166,
"gzipped": 3349,
"treeshaked": {
"rollup": {
"code": 14,
Expand All @@ -28,9 +28,9 @@
}
},
"devtools.js": {
"bundled": 18986,
"minified": 9482,
"gzipped": 3260,
"bundled": 19114,
"minified": 9535,
"gzipped": 3277,
"treeshaked": {
"rollup": {
"code": 28,
Expand Down Expand Up @@ -70,9 +70,9 @@
}
},
"query.js": {
"bundled": 2343,
"minified": 1141,
"gzipped": 567,
"bundled": 2753,
"minified": 1235,
"gzipped": 608,
"treeshaked": {
"rollup": {
"code": 105,
Expand Down
3 changes: 3 additions & 0 deletions src/core/vanilla.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ const readAtomState = <Value>(
// a === atom
const aState = getAtomState(state, a)
if (aState) {
if (aState.e) {
throw aState.e // read error
}
if (aState.p) {
throw aState.p // read promise
}
Expand Down
41 changes: 29 additions & 12 deletions src/query/atomWithQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,52 @@ export function atomWithQuery<
const queryClient = get(getQueryClientAtom)
const options =
typeof createQuery === 'function' ? createQuery(get) : createQuery
let resolve: ((data: TData) => void) | null = null
let settlePromise: ((data: TData | null, err?: TError) => void) | null =
null
const getInitialData = () =>
typeof options.initialData === 'function'
? (options.initialData as InitialDataFunction<TQueryData>)()
: options.initialData
const dataAtom = atom<TData | TQueryData | Promise<TData | TQueryData>>(
getInitialData() ||
new Promise<TData>((r) => {
resolve = r
new Promise<TData>((resolve, reject) => {
settlePromise = (data, err) => {
if (err) {
reject(err)
} else {
resolve(data as TData)
}
}
})
)
let setData: (data: TData) => void = () => {
let setData: (data: TData | Promise<TData>) => void = () => {
throw new Error('atomWithQuery: setting data without mount')
}
let prevData: TData | null = null
const listener = (result: QueryObserverResult<TData, TError>) => {
// TODO error handling
const listener = (
result:
| QueryObserverResult<TData, TError>
| { data?: undefined; error: TError }
) => {
if (result.error) {
if (settlePromise) {
settlePromise(null, result.error)
settlePromise = null
} else {
setData(Promise.reject<TData>(result.error))
}
return
}
if (
result.data === undefined ||
(prevData !== null && equalityFn(prevData, result.data))
) {
return
}
prevData = result.data
if (resolve) {
resolve(result.data)
resolve = null
if (settlePromise) {
settlePromise(result.data)
settlePromise = null
} else {
setData(result.data)
}
Expand All @@ -73,9 +92,7 @@ export function atomWithQuery<
observer
.fetchOptimistic(defaultedOptions)
.then(listener)
.catch(() => {
// TODO error handling
})
.catch((error) => listener({ error }))
dataAtom.onMount = (update) => {
setData = update
const unsubscribe = observer.subscribe(listener)
Expand Down

1 comment on commit 5844f7d

@vercel
Copy link

@vercel vercel bot commented on 5844f7d Jun 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.