diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 84ae999ac88..9af32adda93 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -778,7 +778,7 @@ var BasicModel = AbstractModel.extend({ _.extend(record.data, _changes); def.resolve(changedFields); } - }); + }).fail(def.reject.bind(def)); } else { def.resolve(changedFields); } diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 3b2e634809a..a36cfec075a 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -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: '
' + + '' + + '' + + '' + + '' + + '' + + '
', + 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(); + }); + }); });