-
-
Notifications
You must be signed in to change notification settings - Fork 81
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
Clarity around getPersisted returning undefined #161
Comments
Expected behaviorI think that The documentation says:
It's not entirely clear to me (based on documentation alone) whether the expected behavior upon returned |
I've also been thinking that since it's common for persisters to return result of |
Great analysis. I'm a bit surprised that undefined throws (the Store should ignore invalid content silently) but I'm sure you're right. Once I repro, I'll make sure that is the case, since yes, undefined kind of implies either the underlying file/store/source doesn't exist and the initialContent can be taken. Seems I need to dive back into this corner of the project! |
I can't get it to throw, per se... it appears as an ignored error: test.only('does not error on getPersister returning undefined', async () => {
const store = createStore();
store.setTables({t1: {r1: {c1: 1}}});
const persister = createCustomPersister(
store,
async () => {
console.log('undefined!!!');
return undefined;
},
async () => {},
() => 0,
() => 0,
console.warn,
);
await persister.load();
expect(store.getTables()).toEqual({t1: {r1: {c1: 1}}});
}); Gives:
|
I can provoke similar behavior, however, by firing the persister listener with invalid content (because of the way the various parts of the persister are wrapped in try/catches): test.only('autoLoad silent if persister listener returns invalid', async () => {
let triggerListener = () => {};
const store = createStore();
store.setTables({t1: {r1: {c1: 1}}});
const persister = createCustomPersister(
store,
async () => 1 as any,
async () => {},
(listener) => (triggerListener = listener),
() => 0,
);
await persister.startAutoLoad();
triggerListener(1 as any);
expect(store.getTables()).toEqual({t1: {r1: {c1: 1}}});
}); Gives:
So will land both of theses test cases as well as more tolerance on the setContent method. |
You are totally right. I had a better look and confirmed that the actual throw of an error was coming from my own test harness (which throws the ignored errors when running my persister to expose potential issues in it). |
I wanted to understand the new behavior properly to make sure my mental model is correct, if you have a moment for this, could you confirm that I got it right:
|
I don't have a strong opinion on what's the best behavior for when |
Here is a concrete use-case when The current version of a remote persister keeps track of the last ETag and issues HEAD requests comparing old ETag with current (which is the best way to be compatible with every HTTP server that provides ETags). A variation of it could shoot the real request right-away with const getPersisted = async (): Promise<Content | undefined> => {
const headers = lastEtag === null ? [] : { 'if-none-match': lastEtag };
const response = await fetch(loadUrl, { headers });
if (response.status != 304) {
lastEtag = getETag(response);
return jsonParse(await response.text());
}
}; In this case it's really undesired for |
Yeah, that's a good point. Still some refinement to be done here (at least with making the semantics of undefined clearer). Your mental model on the whole is correct (except in 1, the validateContent is never reached... the persister checks it's an array for itself to decide whether to throw/log or not - since the Store is always silent by design) |
You are right, it seems that this is mostly about clarifying the meaning of So returning Is this correct more or less? I tried to think of some examples where
|
Describe the bug
Hi. Thank you for a great project. I am working on another persister and stumbled onto a small issue.
The type of
createCustomPersister
'sgetPersisted
parameter permits returningPromise<undefined>
, but during theload()
the type of returned value is coerced (insetContentOrChanges
) skipping the check forundefined
which results in e.g.store.setContent
failing like this:The text was updated successfully, but these errors were encountered: