]> git.basschouten.com Git - openhab-addons.git/commitdiff
[jsscripting] Refactor log formatting & Respect toString polyfills (#13844)
authorFlorian Hotze <florianh_dev@icloud.com>
Mon, 5 Dec 2022 19:46:17 +0000 (20:46 +0100)
committerGitHub <noreply@github.com>
Mon, 5 Dec 2022 19:46:17 +0000 (20:46 +0100)
* [jsscripting] Refactor log formatting & Respect toString polyfills
* [jsscripting] Catch errors in log formatting & Improve handling of Java obj
* [jsscripting] Update log format failure message

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js

index b68f05ebc91a369920a256c914bc2d10f5c6a7e4..444955f0d0cbcc4f66132a9d863632d99e9c4f8e 100644 (file)
 
   function stringify (value) {
     try {
-      if (Java.isJavaObject(value) || value instanceof Error) {
-        return value.toString();
-      } else {
-        // special cases
-        if (value === undefined) {
-          return 'undefined';
-        }
-        if (typeof value === 'function') {
-          return '[Function]';
-        }
-        if (value instanceof RegExp) {
-          return value.toString();
-        }
-        // fallback to JSON
+      if (typeof value === 'string') return value;
+      // special cases
+      if (value === undefined) {
+        return 'undefined';
+      }
+      if (value === null) {
+        return 'null';
+      }
+      // JSON.stringify all objects that do not polyfill toString()
+      const str = value.toString();
+      if (typeof value === 'object' && (str === '[object Object]') || str === '[object Java]') {
         return JSON.stringify(value, null, 2);
       }
+      return str;
     } catch (e) {
-      return '[Circular: ' + e + ']';
+      return 'Error: failed to format log message: ' + e;
     }
   }
 
   function format (f) {
-    if (typeof f !== 'string') {
-      const objects = [];
-      for (let index = 0; index < arguments.length; index++) {
-        objects.push(stringify(arguments[index]));
-      }
-      return objects.join(' ');
-    }
-
-    if (arguments.length === 1) return f;
-
-    let i = 1;
-    const args = arguments;
-    const len = args.length;
-    let str = String(f).replace(formatRegExp, function (x) {
-      if (x === '%%') return '%';
-      if (i >= len) return x;
-      switch (x) {
-        case '%s': return String(args[i++]);
-        case '%d': return Number(args[i++]);
-        case '%j':
-          try {
-            return stringify(args[i++]);
-          } catch (_) {
-            return '[Circular]';
+    try {
+      const args = arguments;
+
+      // If there is only one argument, stringify and return it
+      if (args.length === 1) return stringify(f);
+
+      // Else if the first arg is string, do regex string formatting
+      // the number of args after the formatted string must match the number of % placeholder
+      let str;
+      let i = 1;
+      if (typeof f === 'string') {
+        str = String(f).replace(formatRegExp, function (x) {
+          if (x === '%%') return '%';
+          if (i >= args.length) return x;
+          switch (x) {
+            case '%s': return String(args[i++]);
+            case '%d': return Number(args[i++]);
+            case '%j':
+              try {
+                return stringify(args[i++]);
+              } catch (e) {
+                return '[Circular]';
+              }
+              // falls through
+            default:
+              return x;
           }
-          // falls through
-        default:
-          return x;
+        });
       }
-    });
-    for (let x = args[i]; i < len; x = args[++i]) {
-      if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) {
-        str += ' ' + x;
-      } else {
+      // Else stringify and join all args
+      for (let x = args[i]; i < args.length; x = args[++i]) {
         str += ' ' + stringify(x);
       }
+      return str;
+    } catch (e) {
+      return 'Error: failed to format log message: ' + e;
     }
-    return str;
   }
 
   const counters = {};