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
How to catch 422 errors and rollback operations in one store #599
Comments
Essentially what you want to do is perform the equivalent of a revert commit in git, which is what you've pieced together in your There are a lot of pieces here, most of which I'd like to standardize, since this is a common failure scenario. Basically, I'm finding that almost every git command has a useful equivalent that should find its way into orbit. |
@dgeb however that still leaves something unexplained.
What I mean is that the above import JSONAPISource, { JSONAPISerializer } from '@orbit/jsonapi';
import config from '../config/environment';
import { getOwner } from '@ember/application';
class CustomSerializer extends JSONAPISerializer {
resourceKey(type) {
return (type === 'session' || type === 'project') ? 'remoteId' : 'id';
}
}
export default {
create(injections = {}) {
injections.name = 'remote';
injections.namespace = config.apiEndpoint;
injections.SerializerClass = CustomSerializer;
let source = new JSONAPISource(injections);
// This hack is the best I could figure out, but it's hacky and
// not a good solution long term. See https://github.com/orbitjs/orbit/issues/599
source.handleFetchResponseError = function(response, data) {
if (response.status === 422 || response.status === 403 || response.status === 404) {
let owner = getOwner(injections);
let store = owner.lookup('service:store');
this.requestQueue.skip();
store.requestQueue.skip();
}
return JSONAPISource.prototype.handleFetchResponseError.call(this, response, data);
}
return source;
}
}; It seems off that there isn't a single point where I can catch and revert the operation in both scenarios (and having to override |
@cibernox I agree that override should not be needed (and certainly not there), so let's try to reproduce this situation in an integration test. I will add a new private package to the repo for full-app style integration tests that recreate scenarios like this across multiple orbit packages. |
@dgeb Once you've added the package I can help reproducing our scenario with IDB and IDB-bucket. |
@dgeb I created #613 adding one test. Something that surprised me is that despite of the |
As mentioned in #613, this seems to have been resolved. Of course, please open a fresh issue if there's anything outstanding. |
I have an offline-first application in which I need to catch errors, check the error code and react accordingly.
This application has two stores, the
remote
one is aJSONAPISource
. Thebackup
is aIndexedDBSource
. Changes propagate to both sources so I have eventual consistency and everything is non-blocking.I've added and configured
@orbit/indexeddb-bucket
successfully. It all works well in the happy path.The problem happens when the user performs some operation that is added to the bucket and then applied to both sources. The IDB source always succeeds but sometimes the server can reject the request. Typically that will be because of a 422 error (there are other situations but this is the main one).
When that happens, since invalid data will continue to be invalid in the future, I want to remove that operation from the bucket so it's never retried and rollback the changes on the stores it has been applied to (the IDB and the in-memory store).
I manager to hack something that works ok when I have connection:
I'm pretty sure this is not ideal but it kind of works.
However, if when saving the invalid data the user is offline, the request fails with a 500 and the request stays in the bucket to be retried the next time the user reloads the page.
In that situation, when I refresh the page with the connection enabled, Orbit.js retries the uncommitted operation in the bucket that this time reaches the server which responds with a 422 error, but that error doesn't trigger the above code!
I assumed I should be handled the error at a lower level and tried to write request strategy:
I couldn't get the code to hit the debuggers, so I wondered if there is something off in my config.
I'm using ember-orbit, so I working under the assumption that my strategies are automatically registered by placing them in the right folder.
The text was updated successfully, but these errors were encountered: