OD602 orphan-patch-super¶
A patch calls a super method the class it patches does not have.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Correctness | Error | 17.0 and later | yes |
What it reports¶
A super.name() call in a method of patch(Class.prototype, {...}) when neither the class nor
any class it extends has a method, accessor or field name, and no other patch of those classes
adds one. The class is followed through imports and re-exports to the file that declares it.
Owl's Component counts as having setup and render.
Why it matters¶
patch makes super in the patch's methods point at the class's own member, or the previous
patch's. When there is none, super.name is undefined and the call throws a TypeError the
first time the patched method runs. The usual cause is a method renamed or removed upstream
between series: the override no longer overrides anything, and it breaks as soon as it is called.
The rule stays silent when it cannot see every parent: a class extending an expression such as a
mixin call, or a class from a module that is not indexed or not a script, such as an Owl class
other than Component, and a module whose dependencies include one that is not indexed (such as
an Enterprise module, which may patch the class too). A read such as super.name || fallback is
not reported, since it tolerates a missing member. Before 17.0, a patch reached the patched
method through this._super, which the rule does not read.
Example¶
import { patch } from "@web/core/utils/patch";
import { FormController } from "@web/views/form/form_controller";
patch(FormController.prototype, {
async onRecordSave(record, changes) {
await super.onRecordSave(...arguments);
this.notification.add("Saved");
},
});
FormController names this method onRecordSaved, so the patch adds a method nobody calls, and
calling it fails.
import { patch } from "@web/core/utils/patch";
import { FormController } from "@web/views/form/form_controller";
patch(FormController.prototype, {
async onRecordSaved(record, changes) {
await super.onRecordSaved(...arguments);
this.notification.add("Saved");
},
});