[IMP] *: remove guarded catch

This commit removes the promise extension which added the function
`guardedCatch`. It was used to filter server and connection errors from
javascript errors. Instead of using guardedCatch, we should use catch
and check if the reason is a server or connection error if needed and
re-throw the error if it's not handled.

closes odoo/odoo#137702

Task: 3439226
Related: odoo/enterprise#48451
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Michael (mcm)
2023-10-25 15:50:34 +00:00
parent d8627c4e38
commit fcb16a3b1b
32 changed files with 141 additions and 234 deletions
@@ -84,11 +84,7 @@ QUnit.module("base_automation", {}, function () {
await mount(MainComponentsContainer, target, { env });
const errorEvent = new PromiseRejectionEvent("error", {
reason: {
message: error,
legacy: true,
event: $.Event(),
},
reason: error,
promise: null,
cancelable: true,
bubbles: true,
@@ -112,11 +108,7 @@ QUnit.module("base_automation", {}, function () {
await mount(MainComponentsContainer, target, { env });
const errorEvent = new PromiseRejectionEvent("error", {
reason: {
message: error,
legacy: true,
event: $.Event(),
},
reason: error,
promise: null,
cancelable: true,
bubbles: true,
-1
View File
@@ -32,7 +32,6 @@
('remove', 'bus/static/tests/helpers/**/*'),
],
'bus.websocket_worker_assets': [
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'bus/static/src/workers/*',
],
@@ -57,7 +57,6 @@
'web/static/src/views/fields/translation_dialog.scss',
'web/static/src/scss/fontawesome_overridden.scss',
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'web/static/src/session.js',
@@ -128,8 +127,6 @@
# Form style should be computed before
'web/static/src/views/form/button_box/*.scss',
'web/static/src/legacy/legacy_promise_error_handler.js',
'web/static/src/legacy/legacy_rpc_error_handler.js',
'web/static/src/legacy/utils.js',
'mrp_subcontracting/static/src/subcontracting_portal/*',
+31 -18
View File
@@ -5,6 +5,7 @@ import { browser } from '@web/core/browser/browser';
import { ConfirmationDialog } from '@web/core/confirmation_dialog/confirmation_dialog';
import { _t } from '@web/core/l10n/translation';
import { renderToMarkup } from '@web/core/utils/render';
import { RPCError } from '@web/core/network/rpc_service';
publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
selector: '#o_payment_form',
@@ -91,11 +92,14 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
[tokenId],
).then(linkedRecordsInfo => {
this._challengeTokenDeletion(tokenId, linkedRecordsInfo);
}).guardedCatch(error => {
error.event.preventDefault();
this._displayErrorDialog(
_t("Cannot delete payment method"), error.message.data.message
);
}).catch(error => {
if (error instanceof RPCError) {
this._displayErrorDialog(
_t("Cannot delete payment method"), error.data.message
);
} else {
return Promise.reject(error);
}
});
},
@@ -356,10 +360,13 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
'access_token': this.paymentContext['accessToken'],
}).then(() => {
window.location = this.paymentContext['landingRoute'];
}).guardedCatch(error => {
error.event.preventDefault();
this._displayErrorDialog(_t("Cannot save payment method"), error.message.data.message);
this._enableButton(); // The button has been disabled before initiating the flow.
}).catch(error => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Cannot save payment method"), error.data.message);
this._enableButton(); // The button has been disabled before initiating the flow.
} else {
return Promise.reject(error);
}
});
},
@@ -399,10 +406,13 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
providerCode, paymentOptionId, paymentMethodCode, processingValues
);
}
}).guardedCatch(error => {
error.event.preventDefault();
this._displayErrorDialog(_t("Payment processing failed"), error.message.data.message);
this._enableButton(); // The button has been disabled before initiating the flow.
}).catch(error => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
this._enableButton(); // The button has been disabled before initiating the flow.
} else {
return Promise.reject(error);
}
});
},
@@ -500,11 +510,14 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
'token_id': tokenId,
}).then(() => {
browser.location.reload();
}).guardedCatch(error => {
error.event.preventDefault();
this._displayErrorDialog(
_t("Cannot delete payment method"), error.message.data.message
);
}).catch(error => {
if (error instanceof RPCError) {
this._displayErrorDialog(
_t("Cannot delete payment method"), error.data.message
);
} else {
return Promise.reject(error);
}
});
},
@@ -4,6 +4,7 @@ import publicWidget from '@web/legacy/js/public/public_widget';
import { renderToElement } from '@web/core/utils/render';
import { markup } from "@odoo/owl";
import { _t } from '@web/core/l10n/translation';
import { ConnectionLostError, RPCError } from '@web/core/network/rpc_service';
publicWidget.registry.PaymentPostProcessing = publicWidget.Widget.extend({
selector: 'div[name="o_payment_status"]',
@@ -46,10 +47,9 @@ publicWidget.registry.PaymentPostProcessing = publicWidget.Widget.extend({
} else {
self._poll();
}
}).guardedCatch(error => {
error.event.preventDefault();
if (error.message.data) { // Server error.
switch (error.message.data.message) {
}).catch(error => {
if (error instanceof RPCError) { // Server error.
switch (error.data.message) {
case 'retry':
self._poll();
break;
@@ -58,13 +58,15 @@ publicWidget.registry.PaymentPostProcessing = publicWidget.Widget.extend({
break;
default:
self._renderTemplate(
'payment.exception', { error_message: error.message.data.message }
'payment.exception', { error_message: error.data.message }
);
break;
}
} else { // RPC error (server unreachable).
} else if (error instanceof ConnectionLostError) { // RPC error (server unreachable).
self._renderTemplate('payment.rpc_error');
self._poll();
} else {
return Promise.reject(error);
}
});
}, this.timeout);
@@ -3,6 +3,7 @@
import { _t } from '@web/core/l10n/translation';
import paymentForm from '@payment/js/payment_form';
import { RPCError } from '@web/core/network/rpc_service';
paymentForm.include({
@@ -72,12 +73,15 @@ paymentForm.include({
onSubmit: this._adyenOnSubmit.bind(this),
};
this.adyenCheckout = await AdyenCheckout(configuration);
}).guardedCatch((error) => {
error.event.preventDefault();
this._displayErrorDialog(
_t("Cannot display the payment form"), error.message.data.message
);
this._enableButton();
}).catch((error) => {
if (error instanceof RPCError) {
this._displayErrorDialog(
_t("Cannot display the payment form"), error.data.message
);
this._enableButton();
} else {
return Promise.reject(error);
}
});
}
@@ -182,10 +186,13 @@ paymentForm.include({
} else { // The payment reached a final state; redirect to the status page.
window.location = '/payment/status';
}
}).guardedCatch((error) => {
error.event.preventDefault();
this._displayErrorDialog(_t("Payment processing failed"), error.message.data.message);
this._enableButton();
}).catch((error) => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
this._enableButton();
} else {
return Promise.reject(error);
}
});
},
@@ -208,10 +215,13 @@ paymentForm.include({
} else { // The payment reached a final state; redirect to the status page.
window.location = '/payment/status';
}
}).guardedCatch((error) => {
error.event.preventDefault();
this._displayErrorDialog(_t("Payment processing failed"), error.message.data.message);
this._enableButton();
}).catch((error) => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
this._enableButton();
} else {
return Promise.reject(error);
}
});
},
@@ -5,6 +5,7 @@ import { _t } from '@web/core/l10n/translation';
import { loadJS } from '@web/core/assets';
import paymentForm from '@payment/js/payment_form';
import { RPCError } from '@web/core/network/rpc_service';
paymentForm.include({
@@ -145,10 +146,13 @@ paymentForm.include({
'access_token': processingValues.access_token,
}).then(() => {
window.location = '/payment/status';
}).guardedCatch((error) => {
error.event.preventDefault();
this._displayErrorDialog(_t("Payment processing failed"), error.message.data.message);
this._enableButton();
}).catch((error) => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
this._enableButton();
} else {
return Promise.reject(error);
}
});
},
@@ -1,7 +1,7 @@
/** @odoo-module **/
import { _t } from "@web/core/l10n/translation";
import { jsonrpc } from "@web/core/network/rpc_service";
import { jsonrpc, RPCError } from "@web/core/network/rpc_service";
export default {
@@ -22,10 +22,13 @@ export default {
'simulated_state': simulatedPaymentState,
}).then(() => {
window.location = '/payment/status';
}).guardedCatch(error => {
error.event.preventDefault();
this._displayErrorDialog(_t("Payment processing failed"), error.message.data.message);
this._enableButton?.(); // This method doesn't exists in Express Checkout form.
}).catch(error => {
if (error instanceof RPCError) {
this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
this._enableButton?.(); // This method doesn't exists in Express Checkout form.
} else {
return Promise.reject(error);
}
});
},
-2
View File
@@ -110,8 +110,6 @@
'web/static/lib/owl/odoo_module.js',
'web_editor/static/lib/html2canvas.js',
'web/static/lib/zxing-library/zxing-library.js',
# FIXME POSREF legacy dependencies to remove
'web/static/src/legacy/js/promise_extension.js',
# JS framework
('include', 'web._assets_core'),
('remove', 'web/static/src/core/errors/error_handlers.js'), # error handling in PoS is different from the webclient
@@ -186,11 +186,7 @@ export class ClosePosPopup extends AbstractAwaitablePopup {
// We have to handle the error manually otherwise the validation check stops the script.
// In case of "rescue session", we want to display the next popup with "handleClosingError".
// FIXME
if (
!error.message &&
!error.message.data &&
error.message.data.message !== "This session is already closed."
) {
if (!error.data && error.data.message !== "This session is already closed.") {
throw error;
}
}
@@ -6,6 +6,7 @@ import { renderToElement } from "@web/core/utils/render";
import publicWidget from "@web/legacy/js/public/public_widget";
import { post } from "@web/core/network/http_service";
import { Component } from "@odoo/owl";
import { RPCError } from "@web/core/network/rpc_service";
/**
* Widget PortalComposer
@@ -124,12 +125,14 @@ var PortalComposer = publicWidget.Widget.extend({
self.attachments.push(attachment);
self._updateAttachments();
resolve();
}).guardedCatch(function (error) {
self.notification.add(
_t("Could not save file <strong>%s</strong>", escape(file.name)),
{ type: 'warning', sticky: true }
);
resolve();
}).catch(function (error) {
if (error instanceof RPCError) {
self.notification.add(
_t("Could not save file <strong>%s</strong>", escape(file.name)),
{ type: 'warning', sticky: true }
);
resolve();
}
});
});
})).then(function () {
-3
View File
@@ -107,7 +107,6 @@
'web/static/src/views/fields/translation_dialog.scss',
'web/static/src/scss/fontawesome_overridden.scss',
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'web/static/src/session.js',
@@ -180,8 +179,6 @@
# Form style should be computed before
'web/static/src/views/form/button_box/*.scss',
'web/static/src/legacy/legacy_promise_error_handler.js',
'web/static/src/legacy/legacy_rpc_error_handler.js',
'web/static/src/legacy/utils.js',
'web_editor/static/src/js/editor/odoo-editor/src/base_style.scss',
-8
View File
@@ -62,8 +62,6 @@ This module provides the core of the Odoo Web Client.
'web/static/src/views/fields/translation_dialog.scss',
'web/static/src/legacy/scss/ui.scss',
'web/static/src/legacy/js/promise_extension.js',
'web/static/lib/jquery/jquery.js',
'web/static/lib/jquery.ui/jquery-ui.js',
'web/static/lib/popper/popper.js',
@@ -117,8 +115,6 @@ This module provides the core of the Odoo Web Client.
# Form style should be computed before
'web/static/src/views/form/button_box/*.scss',
'web/static/src/legacy/legacy_promise_error_handler.js',
'web/static/src/legacy/legacy_rpc_error_handler.js',
'web/static/src/legacy/utils.js',
'web/static/src/legacy/xml/base.xml',
@@ -131,7 +127,6 @@ This module provides the core of the Odoo Web Client.
'web/static/src/start.js',
],
'web.assets_frontend_minimal': [
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'web/static/src/session.js',
'web/static/src/core/browser/cookie.js',
@@ -228,14 +223,11 @@ This module provides the core of the Odoo Web Client.
'web/static/src/legacy/js/public/public_root_instance.js',
'web/static/src/legacy/js/public/public_widget.js',
'web/static/src/legacy/js/public/signin.js',
'web/static/src/legacy/legacy_promise_error_handler.js',
'web/static/src/legacy/legacy_rpc_error_handler.js',
],
'web.assets_frontend_lazy': [
('include', 'web.assets_frontend'),
# Remove assets_frontend_minimal
('remove', 'web/static/src/legacy/js/promise_extension.js'),
('remove', 'web/static/src/module_loader.js'),
('remove', 'web/static/src/session.js'),
('remove', 'web/static/src/core/browser/cookie.js'),
@@ -61,7 +61,11 @@ export const errorService = {
return;
}
}
if (uncaughtError.event && !uncaughtError.event.defaultPrevented) {
if (
uncaughtError.event &&
!uncaughtError.event.defaultPrevented &&
uncaughtError.traceback
) {
// Log the full traceback instead of letting the browser log the incomplete one
uncaughtError.event.preventDefault();
console.error(uncaughtError.traceback);
@@ -427,8 +427,9 @@ Dialog.confirm = function (owner, message, options) {
}
isBlocked = true;
const callbackRes = callback && callback.apply(this, arguments);
Promise.resolve(callbackRes).guardedCatch(() => {
Promise.resolve(callbackRes).catch((e) => {
isBlocked = false;
return Promise.reject(e);
});
return callbackRes;
};
+2 -2
View File
@@ -302,7 +302,7 @@ var dom = {
_lock();
var result = fct.apply(this, arguments);
Promise.resolve(result).then(_unlock).guardedCatch(_unlock);
Promise.resolve(result).finally(_unlock);
return result;
};
},
@@ -342,7 +342,7 @@ var dom = {
Promise.resolve(dom.DEBOUNCE && delay(dom.DEBOUNCE)).then(function () {
$button.removeClass('pe-none');
const restore = dom.addButtonLoadingEffect($button[0]);
return Promise.resolve(result).then(restore).guardedCatch(restore);
return Promise.resolve(result).finally(restore);
});
return result;
@@ -84,7 +84,7 @@ var ParentedMixin = {
} else if (shouldReject) {
reject();
}
}).guardedCatch(function (reason) {
}).catch(function (reason) {
if (!self.isDestroyed()) {
reject(reason);
} else if (shouldReject) {
@@ -1,11 +1,6 @@
/** @odoo-module **/
import { SERVICES_METADATA } from "@web/env";
import {
ConnectionAbortedError,
ConnectionLostError,
RPCError,
} from "@web/core/network/rpc_service";
import { Component } from "@odoo/owl";
function protectMethod(widget, fn) {
@@ -19,15 +14,7 @@ function protectMethod(widget, fn) {
})
.catch((reason) => {
if (!widget.isDestroyed()) {
if (reason instanceof RPCError || reason instanceof ConnectionLostError) {
// we do not reject an error here because we want to pass through
// the legacy guardedCatch code
reject({ message: reason, event: $.Event(), legacy: true });
} else if (reason instanceof ConnectionAbortedError) {
reject({ message: reason.message, event: $.Event("abort") });
} else {
reject(reason);
}
reject(reason);
}
});
});
@@ -1,23 +0,0 @@
/**
* This file adds a 'guardedCatch' function to the Promise API. This function
* has to be used when we don't want to swallow real errors (crashes), like
* 'catch' does (i.e. basically all the time in Odoo). We only execute the
* 'onRejected' handler if the rejection's reason is not an Error, and we always
* return a rejected Promise to let the rejection bubble up (and trigger the
* 'unhandledrejection' event).
*/
(function () {
var _catch = Promise.prototype.catch;
Promise.prototype.guardedCatch = function (onRejected) {
return _catch.call(this, function (reason) {
const error = (reason instanceof Error && "cause" in reason) ? reason.cause : reason;
if (!error || !(error instanceof Error)) {
if (onRejected) {
onRejected.call(this, reason);
}
}
return Promise.reject(reason);
});
};
})();
@@ -15,6 +15,7 @@ import { MainComponentsContainer } from "@web/core/main_components_container";
import { browser } from '@web/core/browser/browser';
import { _t } from "@web/core/l10n/translation";
import { App, Component, whenReady } from "@odoo/owl";
import { RPCError } from '@web/core/network/rpc_service';
const { Settings } = luxon;
@@ -258,7 +259,12 @@ export const PublicRoot = publicWidget.RootWidget.extend({
_onWidgetsStartRequest: function (ev) {
this._startWidgets(ev.data.$target, ev.data.options)
.then(ev.data.onSuccess)
.guardedCatch(ev.data.onFailure);
.catch((e) => {
ev.data.onFailure(e);
if (!(e instanceof RPCError)) {
return Promise.reject(e);
}
});
},
/**
* Called when the root is notified that the public widgets have to be
@@ -1,38 +0,0 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
/**
* @typedef {import("../env").OdooEnv} OdooEnv
* @typedef {import("../core/errors/error_service").UncaughtPromiseError} UncaughtPromiseError
*/
// -----------------------------------------------------------------------------
// Legacy Promise error handling
// -----------------------------------------------------------------------------
/**
* @param {OdooEnv} env
* @param {Error} error
* @param {Error} originalError
* @returns {boolean}
*/
function legacyRejectPromiseHandler(env, error, originalError) {
if (error.name.startsWith("UncaughtPromiseError")) {
const isLegitError = originalError && originalError instanceof Error;
const isLegacyRPC = originalError && originalError.legacy;
if (!isLegitError && !isLegacyRPC) {
// we consider that a code throwing something that is not an error is
// a case where it is meant as an asynchronous control flow (as legacy
// code is sadly doing). For now, we just want to consider this as a non
// error, so we prevent default it.
error.unhandledRejectionEvent.preventDefault();
return true;
}
}
return false;
}
registry
.category("error_handlers")
.add("legacyRejectPromiseHandler", legacyRejectPromiseHandler, { sequence: 1 });
@@ -1,47 +0,0 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { ConnectionLostError, RPCError } from "../core/network/rpc_service";
import { lostConnectionHandler, rpcErrorHandler } from "@web/core/errors/error_handlers";
const errorHandlerRegistry = registry.category("error_handlers");
/**
* @typedef {import("../env").OdooEnv} OdooEnv
* @typedef {import("../core/errors/error_service").UncaughtError} UncaughError
*/
// -----------------------------------------------------------------------------
// Legacy RPC error handling
// -----------------------------------------------------------------------------
/**
* @param {OdooEnv} env
* @param {UncaughError} error
* @param {Error} originalError
* @returns {boolean}
*/
function legacyRPCErrorHandler(env, error, originalError) {
if (
originalError &&
originalError.legacy &&
originalError.message &&
(originalError.message instanceof RPCError ||
originalError.message instanceof ConnectionLostError)
) {
const event = originalError.event;
originalError = originalError.message;
if (event.isDefaultPrevented()) {
// in theory, here, event was already handled
error.unhandledRejectionEvent.preventDefault();
return true;
}
event.preventDefault();
if (originalError instanceof ConnectionLostError) {
return lostConnectionHandler(env, error, originalError);
}
return rpcErrorHandler(env, error, originalError);
}
return false;
}
errorHandlerRegistry.add("legacyRPCErrorHandler", legacyRPCErrorHandler, { sequence: 97 });
-2
View File
@@ -47,7 +47,6 @@ Odoo Web Editor widget.
'web/static/src/views/fields/translation_dialog.scss',
'web/static/src/scss/fontawesome_overridden.scss',
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'web/static/src/session.js',
@@ -249,7 +248,6 @@ Odoo Web Editor widget.
'web_editor/static/src/js/editor/odoo-editor/test/utils.js'
],
'web_editor.mocha_tests': [
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
# insert module dependencies here
'web/static/src/core/utils/concurrency.js',
@@ -26,6 +26,7 @@ import { LinkTools } from '@web_editor/js/wysiwyg/widgets/link_tools';
import { touching, closest } from "@web/core/utils/ui";
import { _t } from "@web/core/l10n/translation";
import { renderToElement } from "@web/core/utils/render";
import { RPCError } from "@web/core/network/rpc_service";
let cacheSnippetTemplate = {};
@@ -3948,14 +3949,17 @@ var SnippetsMenu = Widget.extend({
_toMutex: true,
reloadWebClient: true,
});
}).guardedCatch(reason => {
reason.event.preventDefault();
this.close();
const message = markup(_t("Could not install module <strong>%s</strong>", escape(name)));
self.notification.add(message, {
type: 'danger',
sticky: true,
});
}).catch(reason => {
if (reason instanceof RPCError) {
this.close();
const message = markup(_t("Could not install module <strong>%s</strong>", escape(name)));
self.notification.add(message, {
type: 'danger',
sticky: true,
});
} else {
return Promise.reject(reason);
}
});
},
}, {
@@ -2597,7 +2597,7 @@ export class Wysiwyg extends Component {
return this[saveElementFuncName]($els, context || this.options.context)
.then(function () {
$els.removeClass('o_dirty');
}).guardedCatch(function (response) {
}).catch(function (response) {
// because ckeditor regenerates all the dom, we can't just
// setup the popover here as everything will be destroyed by
// the DOM regeneration. Add markings instead, and returns a
@@ -2617,7 +2617,7 @@ export class Wysiwyg extends Component {
});
return Promise.all(proms).then(function () {
window.onbeforeunload = null;
}).guardedCatch((failed) => {
}).catch((failed) => {
// If there were errors, re-enable edition
this.cancel(false);
});
@@ -81,8 +81,7 @@ patch(LinkTools.prototype, {
$option.data('value', anchor);
$selectMenu.append($option);
}
always();
}).guardedCatch(always);
}).finally(always);
}
$selectMenu.data("anchor-for", urlInputValue);
},
@@ -456,7 +456,7 @@ const { DateTime } = luxon;
self.restoreBtnLoading();
}
})
.guardedCatch(error => {
.catch(error => {
this.update_status(
'error',
error.status && error.status === 413 ? _t("Uploaded file is too large.") : "",
@@ -3,6 +3,7 @@
import { _t } from "@web/core/l10n/translation";
import publicWidget from "@web/legacy/js/public/public_widget";
import { parseDate, formatDate, serializeDate } from "@web/core/l10n/dates";
import { RPCError } from "@web/core/network/rpc_service";
const { DateTime } = luxon;
publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
@@ -37,8 +38,11 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
_buttonExec: function ($btn, callback) {
// TODO remove once the automatic system which does this lands in master
$btn.prop('disabled', true);
return callback.call(this).guardedCatch(function () {
return callback.call(this).catch(function (e) {
$btn.prop('disabled', false);
if (!(e instanceof RPCError)) {
return Promise.reject(e);
}
});
},
/**
+1 -1
View File
@@ -41,7 +41,7 @@ publicWidget.registry.follow = publicWidget.Widget.extend({
this.rpc('/website_mail/is_follower', {
records: records,
}).then(always).guardedCatch(always);
}).then(always, always);
// not if editable mode to allow designer to edit
if (!this.editableMode) {
@@ -43,7 +43,7 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
return Promise.all([def, this.rpc('/website_mass_mailing/is_subscriber', {
'list_id': this._getListId(),
'subscription_type': inputName,
}).then(always).guardedCatch(always)]);
}).then(always, always)]);
},
/**
* @override
@@ -3,6 +3,7 @@
import publicWidget from "@web/legacy/js/public/public_widget";
import wSaleUtils from "@website_sale/js/website_sale_utils";
import VariantMixin from "@website_sale/js/sale_variant_mixin";
import { RPCError } from "@web/core/network/rpc_service";
// VariantMixin events are overridden on purpose here
// to avoid registering them more than once since they are already registered
@@ -116,12 +117,18 @@ publicWidget.registry.ProductWishlist = publicWidget.Widget.extend(VariantMixin,
if (productId === currentProductId) {
$el.prop("disabled", true).addClass('disabled');
}
}).guardedCatch(function () {
}).catch(function (e) {
$el.prop("disabled", false).removeClass('disabled');
if (!(e instanceof RPCError)) {
return Promise.reject(e);
}
});
}
}).guardedCatch(function () {
}).catch(function (e) {
$el.prop("disabled", false).removeClass('disabled');
if (!(e instanceof RPCError)) {
return Promise.reject(e);
}
});
},
/**
-1
View File
@@ -147,7 +147,6 @@ Featuring
'web/static/src/legacy/scss/modal.scss',
'website/static/src/libs/zoomodoo/zoomodoo.scss',
'web/static/src/legacy/js/promise_extension.js',
'web/static/src/module_loader.js',
'web/static/src/session.js',