[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:
@@ -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,
|
||||
|
||||
@@ -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/*',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 });
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -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',
|
||||
|
||||
|
||||
Reference in New Issue
Block a user