summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2019-03-04 10:35:52 +0100
committerAaron Bohy <aab@odoo.com>2019-03-06 20:07:15 +0100
commit380550f62fd8418f7a425c08720bc9d3cfc79131 (patch)
treef212043eac1e24a157900e980a16b8d1d8b1291a /addons/web/static/src/js
parent96b03192399164d776b2e326c1251c0400c61c99 (diff)
[IMP] web: don't swallow errors in async handlers
This commit 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). When the promise has been rejected because of a real error, the rejected Promises chain bubbles up to the top and triggers the 'unhandledrejection' event (triggered on all browsers thanks to the unhandled-rejection-polyfill lib). We then add a listener on that event to display real errors with the CrashManager. Part of task 1896658 Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Christophe Matthieu <chm@odoo.com> Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: David Monjoie <dmo@odoo.com> Co-authored-by: Martin Geubelle <mge@odoo.com> Co-authored-by: svs-odoo <svs@odoo.com> Co-authored-by: Vincent Schippefilt <vsc@odoo.com>
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/promise_extension.js22
-rw-r--r--addons/web/static/src/js/services/crash_manager.js22
2 files changed, 43 insertions, 1 deletions
diff --git a/addons/web/static/src/js/promise_extension.js b/addons/web/static/src/js/promise_extension.js
new file mode 100644
index 00000000000..4758975c712
--- /dev/null
+++ b/addons/web/static/src/js/promise_extension.js
@@ -0,0 +1,22 @@
+/**
+ * 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) {
+ if (!reason || !(reason instanceof Error)) {
+ if (onRejected) {
+ onRejected.call(this, reason);
+ }
+ }
+ return Promise.reject(reason);
+ });
+ };
+})();
diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js
index 31aa178dc1b..db88d688505 100644
--- a/addons/web/static/src/js/services/crash_manager.js
+++ b/addons/web/static/src/js/services/crash_manager.js
@@ -20,9 +20,29 @@ var map_title ={
};
var CrashManager = core.Class.extend({
- init: function() {
+ init: function () {
+ var self = this;
this.active = true;
this.isConnected = true;
+
+ // listen to unhandled rejected promises, and throw an error when the
+ // promise has been rejected due to a crash
+ window.addEventListener('unhandledrejection', function (ev) {
+ if (ev.reason && ev.reason instanceof Error) {
+ var traceback = ev.reason.stack;
+ self.show_error({
+ type: _t("Odoo Client Error"),
+ message: '',
+ data: {debug: _t('Traceback:') + "\n" + traceback},
+ });
+ } else {
+ // the rejection is not due to an Error, so prevent the browser
+ // from displaying an 'unhandledrejection' error in the console
+ ev.stopPropagation();
+ ev.stopImmediatePropagation();
+ ev.preventDefault();
+ }
+ });
},
enable: function () {
this.active = true;