From e2b85d4613d56d40c5361470fb03d946bf7dc823 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= <ged@odoo.com>
Date: Thu, 25 Feb 2021 14:28:59 +0000
Subject: [PATCH] [REF] web: move error handling code to other file

---
 addons/web/static/src/js/core/error_utils.js  | 67 +++++++++++++++++++
 .../static/src/js/services/crash_manager.js   | 65 +-----------------
 addons/web/views/webclient_templates.xml      |  1 +
 3 files changed, 69 insertions(+), 64 deletions(-)
 create mode 100644 addons/web/static/src/js/core/error_utils.js

diff --git a/addons/web/static/src/js/core/error_utils.js b/addons/web/static/src/js/core/error_utils.js
new file mode 100644
index 000000000000..9bdc0a1009fd
--- /dev/null
+++ b/addons/web/static/src/js/core/error_utils.js
@@ -0,0 +1,67 @@
+/** @odoo-module **/
+
+import { loadJS } from "web.ajax";
+
+/**
+ * Format the traceback of an error.  Basically, we just add the error message
+ * in the traceback if necessary (Chrome already does it by default, but not
+ * other browser. yay for non standard APIs)
+ *
+ * @param {Error} error 
+ * @returns {string}
+ */
+export function formatTraceback(error) {
+  const traceback = error.stack;
+  // Error.prototype.stack is non-standard.
+  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
+  // However, most engines provide an implementation.
+  // In particular, Chrome formats the contents of Error.stack
+  // https://v8.dev/docs/stack-trace-api#compatibility
+  const browserDetection = new BrowserDetection();
+  if (browserDetection.isBrowserChrome()) {
+      return error.stack;
+  } else {
+      return `${_t("Error:")} ${error.message}\n${error.stack}`;
+  }
+}
+
+/**
+* Returns an annotated traceback from an error. This is asynchronous because
+* it needs to fetch the sourcemaps for each script involved in the error,
+* then compute the correct file/line numbers and add the information to the
+* correct line.
+* 
+* @param {Error} error 
+* @returns {Promise<string>}
+*/
+export async function annotateTraceback(error) {
+  const traceback = formatTraceback(error);
+  await loadJS('/web/static/lib/stacktracejs/stacktrace.js');
+  const frames = await StackTrace.fromError(error);
+  const lines = traceback.split('\n');
+  if (lines[lines.length-1].trim() === "") {
+      // firefox traceback have an empty line at the end
+      lines.splice(-1);
+  }
+
+  // Chrome stacks contains some lines with (index 0) which apparently
+  // corresponds to some native functions (at least Promise.all). We need to
+  // ignore them because they will not correspond to a stackframe.
+  const skips = lines.filter(l => l.includes("(index 0")).length;
+  const offset = lines.length - frames.length - skips;
+  let lineIndex = offset;
+  let frameIndex = 0;
+  while (frameIndex < frames.length) {
+      const line = lines[lineIndex];
+      if (line.includes("(index 0)")) {
+          lineIndex++;
+          continue;
+      }
+      const frame = frames[frameIndex];
+      const info = ` (${frame.fileName}:${frame.lineNumber})`;
+      lines[lineIndex] = line + info;
+      lineIndex++;
+      frameIndex++;
+  }
+  return lines.join('\n');
+}
diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js
index 7bd3e58e8544..eb31131d7dc7 100644
--- a/addons/web/static/src/js/services/crash_manager.js
+++ b/addons/web/static/src/js/services/crash_manager.js
@@ -17,6 +17,7 @@ var Dialog = require('web.Dialog');
 var ErrorDialogRegistry = require('web.ErrorDialogRegistry');
 var Widget = require('web.Widget');
 var config = require('web.config');
+var { formatTraceback, annotateTraceback} = require("@web/js/core/error_utils");
 
 var _t = core._t;
 var _lt = core._lt;
@@ -29,70 +30,6 @@ window.addEventListener('unhandledrejection', ev =>
 
 let active = true;
 
-/**
- * Format the traceback of an error.  Basically, we just add the error message
- * in the traceback if necessary (Chrome already does it by default, but not
- * other browser. yay for non standard APIs)
- *
- * @param {Error} error 
- * @returns {string}
- */
-function formatTraceback(error) {
-    const traceback = error.stack;
-    // Error.prototype.stack is non-standard.
-    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
-    // However, most engines provide an implementation.
-    // In particular, Chrome formats the contents of Error.stack
-    // https://v8.dev/docs/stack-trace-api#compatibility
-    const browserDetection = new BrowserDetection();
-    if (browserDetection.isBrowserChrome()) {
-        return error.stack;
-    } else {
-        return `${_t("Error:")} ${error.message}\n${error.stack}`;
-    }
-}
-
-/**
- * Returns an annotated traceback from an error. This is asynchronous because
- * it needs to fetch the sourcemaps for each script involved in the error,
- * then compute the correct file/line numbers and add the information to the
- * correct line.
- * 
- * @param {Error} error 
- * @returns {Promise<string>}
- */
-async function annotateTraceback(error) {
-    const traceback = formatTraceback(error);
-    await ajax.loadJS('/web/static/lib/stacktracejs/stacktrace.js');
-    const frames = await StackTrace.fromError(error);
-    const lines = traceback.split('\n');
-    if (lines[lines.length-1].trim() === "") {
-        // firefox traceback have an empty line at the end
-        lines.splice(-1);
-    }
-
-    // Chrome stacks contains some lines with (index 0) which apparently
-    // corresponds to some native functions (at least Promise.all). We need to
-    // ignore them because they will not correspond to a stackframe.
-    const skips = lines.filter(l => l.includes("(index 0")).length;
-    const offset = lines.length - frames.length - skips;
-    let lineIndex = offset;
-    let frameIndex = 0;
-    while (frameIndex < frames.length) {
-        const line = lines[lineIndex];
-        if (line.includes("(index 0)")) {
-            lineIndex++;
-            continue;
-        }
-        const frame = frames[frameIndex];
-        const info = ` (${frame.fileName}:${frame.lineNumber})`;
-        lines[lineIndex] = line + info;
-        lineIndex++;
-        frameIndex++;
-    }
-    return lines.join('\n');
-}
-
 /**
  * An extension of Dialog Widget to render the warnings and errors on the website.
  * Extend it with your template of choice like ErrorDialog/WarningDialog
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 7effc9952da2..60982a48392d 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -166,6 +166,7 @@
         <script type="text/javascript" src="/web/static/src/js/services/local_storage_service.js"></script>
         <script type="text/javascript" src="/web/static/src/js/services/notification_service.js"></script>
         <script type="text/javascript" src="/web/static/src/js/services/crash_manager.js"></script>
+        <script type="text/javascript" src="/web/static/src/js/core/error_utils.js"></script>
         <script type="text/javascript" src="/web/static/src/js/services/session_storage_service.js"></script>
 
         <script type="text/javascript" src="/web/static/src/js/tools/debug_manager.js"></script>
-- 
GitLab