[FIX] web(_editor): protect RPCs from component destruction
The rpc service has a protection (when used via useService) that prevents the returned promise from being resolved/rejected if the component has been destroyed meanwhile. However, as the FormView still uses the legacy BasicModel, all rpcs done by its model do not go through our new rpc service. As a consequence, before this commit, they did not benefit from the protection. This caused a non deterministic issue in the main flow tour. This commit implements a similar protection as the rpc service, but specialized for the BasicRelationalModel, which redirects all RPCs done by the BasicModel. This change highlighted two scenarios where we sometimes performed RPCs (or could perform RPCs) on a destroyed component. This commit fixes those as well. X-original-commit: f613e916d5e8b465fc360e340094c09037450ff1 Part-of: odoo/odoo#105332
This commit is contained in:
@@ -141,10 +141,9 @@ var ServicesMixin = {
|
||||
prom.abort = function () {};
|
||||
}
|
||||
var abort = prom.abort ? prom.abort : prom.reject;
|
||||
if (!abort) {
|
||||
throw new Error("a rpc promise should always have a reject function");
|
||||
if (abort) {
|
||||
prom.abort = abort.bind(prom);
|
||||
}
|
||||
prom.abort = abort.bind(prom);
|
||||
return prom;
|
||||
},
|
||||
loadFieldView: function (modelName, context, view_id, view_type, options) {
|
||||
|
||||
@@ -1099,6 +1099,8 @@ export class RelationalModel extends Model {
|
||||
throw "only record root type is supported";
|
||||
}
|
||||
|
||||
this.__component = params.component;
|
||||
|
||||
this.root = null;
|
||||
|
||||
this.__bm__ = new BasicModel(this, {
|
||||
@@ -1320,7 +1322,25 @@ export class RelationalModel extends Model {
|
||||
if (payload.service === "ajax" && payload.method === "rpc") {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
args = args.concat(ev.target);
|
||||
return payload.callback(owl.Component.env.session.rpc(...args));
|
||||
if (owl.status(this.__component) === "destroyed") {
|
||||
console.warn("Component is destroyed");
|
||||
return payload.callback(Promise.resolve());
|
||||
}
|
||||
const prom = new Promise((resolve, reject) => {
|
||||
owl.Component.env.session
|
||||
.rpc(...args)
|
||||
.then((value) => {
|
||||
if (owl.status(this.__component) !== "destroyed") {
|
||||
resolve(value);
|
||||
}
|
||||
})
|
||||
.guardedCatch((reason) => {
|
||||
if (owl.status(this.__component) !== "destroyed") {
|
||||
reject(reason);
|
||||
}
|
||||
});
|
||||
});
|
||||
return payload.callback(prom);
|
||||
} else if (payload.service === "notification") {
|
||||
return this.notificationService.add(payload.message, {
|
||||
className: payload.className,
|
||||
|
||||
@@ -130,6 +130,7 @@ export class FormController extends Component {
|
||||
rootType: "record",
|
||||
mode,
|
||||
beforeLoadProm,
|
||||
component: this,
|
||||
},
|
||||
{
|
||||
ignoreUseSampleModel: true,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useService } from "@web/core/utils/hooks";
|
||||
import { evaluateExpr } from "@web/core/py_js/py";
|
||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
|
||||
import { useEnv, useSubEnv } from "@odoo/owl";
|
||||
import { status, useEnv, useSubEnv } from "@odoo/owl";
|
||||
|
||||
function disableButtons(el) {
|
||||
// WOWL: can we do this non-imperatively?
|
||||
@@ -86,7 +86,7 @@ export function useViewButtons(model, ref, options = {}) {
|
||||
context: params.context || {}, //LPE FIXME new Context(payload.env.context).eval();
|
||||
buttonContext,
|
||||
onClose: async () => {
|
||||
if (!closeDialog) {
|
||||
if (!closeDialog && status(comp) !== "destroyed") {
|
||||
const reload = options.reload || (() => model.root.load());
|
||||
await reload();
|
||||
comp.render(true); // FIXME WOWL reactivity
|
||||
|
||||
@@ -160,7 +160,6 @@ export class HtmlField extends Component {
|
||||
if (this.resizerHandleObserver) {
|
||||
this.resizerHandleObserver.disconnect();
|
||||
}
|
||||
this.updateValue();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user