[FIX] web: properly react when save operation fails (form)
Before this commit, the save method in the basic model did not properly react when the rpc fails. In that case, the returned deferred stayed indefinitely in the 'pending' state. This is a big problem, because the basic controller put that deferred in a mutex. As a result, every subsequent operations (including field changes!) were indefinitely delayed. To reproduce the issue, you can find any form view where some python business logic will cause a fail in some cases. For example, create a new inventory adjustement, click on 'Start inventory', then add a line in the x2many with the same product as another line. Saving that record will fail, but then, the form view is broken: no interaction will work.
This commit is contained in:
@@ -778,7 +778,7 @@ var BasicModel = AbstractModel.extend({
|
||||
_.extend(record.data, _changes);
|
||||
def.resolve(changedFields);
|
||||
}
|
||||
});
|
||||
}).fail(def.reject.bind(def));
|
||||
} else {
|
||||
def.resolve(changedFields);
|
||||
}
|
||||
|
||||
@@ -4575,5 +4575,48 @@ QUnit.module('Views', {
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('form view is not broken if save operation fails', function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<group>' +
|
||||
'<field name="foo"/>' +
|
||||
'</group>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method);
|
||||
if (args.method === 'write' && args.args[1].foo === 'incorrect value') {
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
form.$('input[name="foo"]').val("incorrect value").trigger("input");
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
form.$('input[name="foo"]').val("correct value").trigger("input");
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
assert.verifySteps([
|
||||
'read', // initial read to render the view
|
||||
'write', // write on save (it fails, does not trigger a read)
|
||||
'write', // write on save (it works)
|
||||
'read' // read on reload
|
||||
]);
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user