-
-
Notifications
You must be signed in to change notification settings - Fork 589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): Allow retries for errored async reads #705
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pmndrs/jotai/5YLw1D1DieaXtDJsxuzLoWQCfC59 |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 3362181:
|
@@ -95,32 +70,3 @@ it('writable count state', async () => { | |||
fireEvent.click(getByText('button')) | |||
await findByText('count: 9') | |||
}) | |||
|
|||
// FIXME we would like to support retry | |||
it.skip('count state with error', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test wasn't valid - an observable can't recover from an error state. For the notion of "retrying" observables to work, the error would never reach atomWithObservable
, so the retrying logic is out of scope for jotai.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I didn't know about the observable error behavior, and created this test. But, it's an expected behavior.
Now, you find the actual issue of error async reads, and fix it. Very very nice.
@@ -177,6 +177,7 @@ export const createStore = ( | |||
return | |||
} | |||
atomState.c?.() // cancel read promise | |||
delete atomState.e // read error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was being done when writing to a sync atom, but not an async atom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow! Nice catch!
Feels like you have fairly deeper understanding of core.
e878929
to
e018bd2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing. You did great work here.
@@ -177,6 +177,7 @@ export const createStore = ( | |||
return | |||
} | |||
atomState.c?.() // cancel read promise | |||
delete atomState.e // read error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow! Nice catch!
Feels like you have fairly deeper understanding of core.
@@ -95,32 +70,3 @@ it('writable count state', async () => { | |||
fireEvent.click(getByText('button')) | |||
await findByText('count: 9') | |||
}) | |||
|
|||
// FIXME we would like to support retry | |||
it.skip('count state with error', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I didn't know about the observable error behavior, and created this test. But, it's an expected behavior.
Now, you find the actual issue of error async reads, and fix it. Very very nice.
tests/error.test.tsx
Outdated
@@ -492,7 +492,7 @@ describe('error recovery', () => { | |||
await findByText('Value: 1') | |||
}) | |||
|
|||
it.only('recovers from async errors', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops - thank you!
Yes, that's my plan too. Seems like a test fails. Is this because our tests are not stable enough because we don't properly use fake timers? |
This was because of less mode and meant the atom state was shared between tests I've fixed it now - could you run the workflow again? |
I see. |
When changing a dependency for an atom in an error state, the derived atom's read function is re-run.
We'd expect that if that re-run is successful,
useAtom
will return the new value.This is currently the case with sync atoms, but not async atoms. This PR fixes that, and adds tests (the async variant was failing, but the sync one wasn't).
Fixes #601