diff --git a/addons/base_automation/static/tests/base_automation_error_dialog.js b/addons/base_automation/static/tests/base_automation_error_dialog.js index f0ae2a60417..2d6ff31a62f 100644 --- a/addons/base_automation/static/tests/base_automation_error_dialog.js +++ b/addons/base_automation/static/tests/base_automation_error_dialog.js @@ -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, diff --git a/addons/bus/__manifest__.py b/addons/bus/__manifest__.py index f1dfdae281b..d29765fe5d8 100644 --- a/addons/bus/__manifest__.py +++ b/addons/bus/__manifest__.py @@ -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/*', ], diff --git a/addons/mrp_subcontracting/__manifest__.py b/addons/mrp_subcontracting/__manifest__.py index 3c95ac63297..3740563ac74 100644 --- a/addons/mrp_subcontracting/__manifest__.py +++ b/addons/mrp_subcontracting/__manifest__.py @@ -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/*', diff --git a/addons/payment/static/src/js/payment_form.js b/addons/payment/static/src/js/payment_form.js index fbe1697816e..d5829fc37a4 100644 --- a/addons/payment/static/src/js/payment_form.js +++ b/addons/payment/static/src/js/payment_form.js @@ -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); + } }); }, diff --git a/addons/payment/static/src/js/post_processing.js b/addons/payment/static/src/js/post_processing.js index 83b383d36f4..fc9556397f0 100644 --- a/addons/payment/static/src/js/post_processing.js +++ b/addons/payment/static/src/js/post_processing.js @@ -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); diff --git a/addons/payment_adyen/static/src/js/payment_form.js b/addons/payment_adyen/static/src/js/payment_form.js index d19ebd586b1..2fd502da0ef 100644 --- a/addons/payment_adyen/static/src/js/payment_form.js +++ b/addons/payment_adyen/static/src/js/payment_form.js @@ -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); + } }); }, diff --git a/addons/payment_authorize/static/src/js/payment_form.js b/addons/payment_authorize/static/src/js/payment_form.js index 4f85bc07198..beba66e971b 100644 --- a/addons/payment_authorize/static/src/js/payment_form.js +++ b/addons/payment_authorize/static/src/js/payment_form.js @@ -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); + } }); }, diff --git a/addons/payment_demo/static/src/js/payment_demo_mixin.js b/addons/payment_demo/static/src/js/payment_demo_mixin.js index c25673761db..09614c584c1 100644 --- a/addons/payment_demo/static/src/js/payment_demo_mixin.js +++ b/addons/payment_demo/static/src/js/payment_demo_mixin.js @@ -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); + } }); }, diff --git a/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/__manifest__.py index 4141441a938..fd2d5a9dd1c 100644 --- a/addons/point_of_sale/__manifest__.py +++ b/addons/point_of_sale/__manifest__.py @@ -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 diff --git a/addons/point_of_sale/static/src/app/navbar/closing_popup/closing_popup.js b/addons/point_of_sale/static/src/app/navbar/closing_popup/closing_popup.js index ba5c5f6788d..0afd936ca74 100644 --- a/addons/point_of_sale/static/src/app/navbar/closing_popup/closing_popup.js +++ b/addons/point_of_sale/static/src/app/navbar/closing_popup/closing_popup.js @@ -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; } } diff --git a/addons/portal/static/src/js/portal_composer.js b/addons/portal/static/src/js/portal_composer.js index fed8af22af9..3f66c6be5d8 100644 --- a/addons/portal/static/src/js/portal_composer.js +++ b/addons/portal/static/src/js/portal_composer.js @@ -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 %s", escape(file.name)), - { type: 'warning', sticky: true } - ); - resolve(); + }).catch(function (error) { + if (error instanceof RPCError) { + self.notification.add( + _t("Could not save file %s", escape(file.name)), + { type: 'warning', sticky: true } + ); + resolve(); + } }); }); })).then(function () { diff --git a/addons/project/__manifest__.py b/addons/project/__manifest__.py index cc14f87e338..907aae927b5 100644 --- a/addons/project/__manifest__.py +++ b/addons/project/__manifest__.py @@ -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', diff --git a/addons/web/__manifest__.py b/addons/web/__manifest__.py index aee3c669aeb..31991dbaeaf 100644 --- a/addons/web/__manifest__.py +++ b/addons/web/__manifest__.py @@ -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'), diff --git a/addons/web/static/src/core/errors/error_service.js b/addons/web/static/src/core/errors/error_service.js index 3e147222594..2a291351dd6 100644 --- a/addons/web/static/src/core/errors/error_service.js +++ b/addons/web/static/src/core/errors/error_service.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); diff --git a/addons/web/static/src/legacy/js/core/dialog.js b/addons/web/static/src/legacy/js/core/dialog.js index f39a1b605f1..822eff5dcb4 100644 --- a/addons/web/static/src/legacy/js/core/dialog.js +++ b/addons/web/static/src/legacy/js/core/dialog.js @@ -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; }; diff --git a/addons/web/static/src/legacy/js/core/dom.js b/addons/web/static/src/legacy/js/core/dom.js index 636feda7f10..80b693341ed 100644 --- a/addons/web/static/src/legacy/js/core/dom.js +++ b/addons/web/static/src/legacy/js/core/dom.js @@ -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; diff --git a/addons/web/static/src/legacy/js/core/mixins.js b/addons/web/static/src/legacy/js/core/mixins.js index cfad2af7473..5a5d64064fd 100644 --- a/addons/web/static/src/legacy/js/core/mixins.js +++ b/addons/web/static/src/legacy/js/core/mixins.js @@ -84,7 +84,7 @@ var ParentedMixin = { } else if (shouldReject) { reject(); } - }).guardedCatch(function (reason) { + }).catch(function (reason) { if (!self.isDestroyed()) { reject(reason); } else if (shouldReject) { diff --git a/addons/web/static/src/legacy/js/core/service_mixins.js b/addons/web/static/src/legacy/js/core/service_mixins.js index 6e2a21a1755..ffddedc5d13 100644 --- a/addons/web/static/src/legacy/js/core/service_mixins.js +++ b/addons/web/static/src/legacy/js/core/service_mixins.js @@ -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); } }); }); diff --git a/addons/web/static/src/legacy/js/promise_extension.js b/addons/web/static/src/legacy/js/promise_extension.js deleted file mode 100644 index 9e12e1cc713..00000000000 --- a/addons/web/static/src/legacy/js/promise_extension.js +++ /dev/null @@ -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); - }); - }; -})(); diff --git a/addons/web/static/src/legacy/js/public/public_root.js b/addons/web/static/src/legacy/js/public/public_root.js index 177efbfc778..27bb5bc46dd 100644 --- a/addons/web/static/src/legacy/js/public/public_root.js +++ b/addons/web/static/src/legacy/js/public/public_root.js @@ -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 diff --git a/addons/web/static/src/legacy/legacy_promise_error_handler.js b/addons/web/static/src/legacy/legacy_promise_error_handler.js deleted file mode 100644 index 0b5eab6c0a1..00000000000 --- a/addons/web/static/src/legacy/legacy_promise_error_handler.js +++ /dev/null @@ -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 }); diff --git a/addons/web/static/src/legacy/legacy_rpc_error_handler.js b/addons/web/static/src/legacy/legacy_rpc_error_handler.js deleted file mode 100644 index 15158225b8d..00000000000 --- a/addons/web/static/src/legacy/legacy_rpc_error_handler.js +++ /dev/null @@ -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 }); diff --git a/addons/web_editor/__manifest__.py b/addons/web_editor/__manifest__.py index 3a3cb1f0095..f2740e33eb5 100644 --- a/addons/web_editor/__manifest__.py +++ b/addons/web_editor/__manifest__.py @@ -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', diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 8ff6e0b6df8..052cf837250 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.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 %s", 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 %s", escape(name))); + self.notification.add(message, { + type: 'danger', + sticky: true, + }); + } else { + return Promise.reject(reason); + } }); }, }, { diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index f7a79b3220a..3c7c72c1ce0 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -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); }); diff --git a/addons/website/static/src/js/editor/widget_link.js b/addons/website/static/src/js/editor/widget_link.js index 201b1642a67..5bc26ac4401 100644 --- a/addons/website/static/src/js/editor/widget_link.js +++ b/addons/website/static/src/js/editor/widget_link.js @@ -81,8 +81,7 @@ patch(LinkTools.prototype, { $option.data('value', anchor); $selectMenu.append($option); } - always(); - }).guardedCatch(always); + }).finally(always); } $selectMenu.data("anchor-for", urlInputValue); }, diff --git a/addons/website/static/src/snippets/s_website_form/000.js b/addons/website/static/src/snippets/s_website_form/000.js index a50c33df54a..051b509e083 100644 --- a/addons/website/static/src/snippets/s_website_form/000.js +++ b/addons/website/static/src/snippets/s_website_form/000.js @@ -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.") : "", diff --git a/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js b/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js index 55251d906e8..12d7e13d19a 100644 --- a/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js +++ b/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js @@ -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); + } }); }, /** diff --git a/addons/website_mail/static/src/js/follow.js b/addons/website_mail/static/src/js/follow.js index ee95dce05f0..58e9e193856 100644 --- a/addons/website_mail/static/src/js/follow.js +++ b/addons/website_mail/static/src/js/follow.js @@ -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) { diff --git a/addons/website_mass_mailing/static/src/js/website_mass_mailing.js b/addons/website_mass_mailing/static/src/js/website_mass_mailing.js index fe0c6137b52..117b5d7afc5 100644 --- a/addons/website_mass_mailing/static/src/js/website_mass_mailing.js +++ b/addons/website_mass_mailing/static/src/js/website_mass_mailing.js @@ -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 diff --git a/addons/website_sale_wishlist/static/src/js/website_sale_wishlist.js b/addons/website_sale_wishlist/static/src/js/website_sale_wishlist.js index b457d4cbcee..f0a798f10dc 100644 --- a/addons/website_sale_wishlist/static/src/js/website_sale_wishlist.js +++ b/addons/website_sale_wishlist/static/src/js/website_sale_wishlist.js @@ -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); + } }); }, /** diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py index 522e48eae7f..fb0cac56db9 100644 --- a/addons/website_slides/__manifest__.py +++ b/addons/website_slides/__manifest__.py @@ -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',