Browse Source

refactor: cleanup web-frame-init.js (#14516)

* refactor: add error-utils.js

* fix exception handling for asyncWebFrameMethods

* remove dead code

* handle exceptions

* rename rehydratedError to deserializedError

* Revert "handle exceptions"

This reverts commit 396b179948b137f9e525e9ebba4f7c6e9bf19429.
Milan Burda 6 years ago
parent
commit
0821edc843
4 changed files with 53 additions and 65 deletions
  1. 1 0
      filenames.gni
  2. 3 34
      lib/browser/api/web-contents.js
  3. 35 0
      lib/common/error-utils.js
  4. 14 31
      lib/renderer/web-frame-init.js

+ 1 - 0
filenames.gni

@@ -56,6 +56,7 @@ filenames = {
     "lib/common/api/shell.js",
     "lib/common/atom-binding-setup.js",
     "lib/common/buffer-utils.js",
+    "lib/common/error-utils.js",
     "lib/common/init.js",
     "lib/common/parse-features-string.js",
     "lib/common/reset-search-paths.js",

+ 3 - 34
lib/browser/api/web-contents.js

@@ -6,6 +6,8 @@ const path = require('path')
 const url = require('url')
 const {app, ipcMain, session, NavigationController, deprecate} = electron
 
+const errorUtils = require('../../common/error-utils')
+
 // session is not used here, the purpose is to make sure session is initalized
 // before the webContents module.
 // eslint-disable-next-line
@@ -111,17 +113,6 @@ const webFrameMethods = [
   'setLayoutZoomLevelLimits',
   'setVisualZoomLevelLimits'
 ]
-const webFrameMethodsWithResult = []
-
-const errorConstructors = {
-  Error,
-  EvalError,
-  RangeError,
-  ReferenceError,
-  SyntaxError,
-  TypeError,
-  URIError
-}
 
 const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
   return new Promise((resolve, reject) => {
@@ -131,40 +122,18 @@ const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
         if (typeof callback === 'function') callback(result)
         resolve(result)
       } else {
-        if (error.__ELECTRON_SERIALIZED_ERROR__ && errorConstructors[error.name]) {
-          const rehydratedError = new errorConstructors[error.name](error.message)
-          rehydratedError.stack = error.stack
-
-          reject(rehydratedError)
-        } else {
-          reject(error)
-        }
+        reject(errorUtils.deserialize(error))
       }
     })
   })
 }
 
-const syncWebFrameMethods = function (requestId, method, callback, ...args) {
-  this.send('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', requestId, method, args)
-  ipcMain.once(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, result) {
-    if (callback) callback(result)
-  })
-}
-
 for (const method of webFrameMethods) {
   WebContents.prototype[method] = function (...args) {
     this.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', method, args)
   }
 }
 
-for (const method of webFrameMethodsWithResult) {
-  WebContents.prototype[method] = function (...args) {
-    const callback = args[args.length - 1]
-    const actualArgs = args.slice(0, args.length - 2)
-    syncWebFrameMethods.call(this, getNextId(), method, callback, ...actualArgs)
-  }
-}
-
 // Make sure WebContents::executeJavaScript would run the code only when the
 // WebContents has been loaded.
 WebContents.prototype.executeJavaScript = function (code, hasUserGesture, callback) {

+ 35 - 0
lib/common/error-utils.js

@@ -0,0 +1,35 @@
+'use strict'
+
+const constructors = new Map([
+  [Error.name, Error],
+  [EvalError.name, EvalError],
+  [RangeError.name, RangeError],
+  [ReferenceError.name, ReferenceError],
+  [SyntaxError.name, SyntaxError],
+  [TypeError.name, TypeError],
+  [URIError.name, URIError]
+])
+
+exports.deserialize = function (error) {
+  if (error.__ELECTRON_SERIALIZED_ERROR__ && constructors.has(error.name)) {
+    const constructor = constructors.get(error.name)
+    const deserializedError = new constructor(error.message)
+    deserializedError.stack = error.stack
+    return deserializedError
+  }
+  return error
+}
+
+exports.serialize = function (error) {
+  if (error instanceof Error) {
+    // Errors get lost, because: JSON.stringify(new Error('Message')) === {}
+    // Take the serializable properties and construct a generic object
+    return {
+      message: error.message,
+      stack: error.stack,
+      name: error.name,
+      __ELECTRON_SERIALIZED_ERROR__: true
+    }
+  }
+  return error
+}

+ 14 - 31
lib/renderer/web-frame-init.js

@@ -1,38 +1,21 @@
-const electron = require('electron')
+const {ipcRenderer, webFrame} = require('electron')
+const errorUtils = require('../common/error-utils')
 
 module.exports = () => {
   // Call webFrame method
-  electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => {
-    electron.webFrame[method](...args)
+  ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => {
+    webFrame[method](...args)
   })
 
-  electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => {
-    const result = electron.webFrame[method](...args)
-    event.sender.send(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, result)
-  })
-
-  electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => {
-    const responseCallback = function (result) {
-      Promise.resolve(result)
-        .then((resolvedResult) => {
-          event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, null, resolvedResult)
-        })
-        .catch((resolvedError) => {
-          if (resolvedError instanceof Error) {
-            // Errors get lost, because: JSON.stringify(new Error('Message')) === {}
-            // Take the serializable properties and construct a generic object
-            resolvedError = {
-              message: resolvedError.message,
-              stack: resolvedError.stack,
-              name: resolvedError.name,
-              __ELECTRON_SERIALIZED_ERROR__: true
-            }
-          }
-
-          event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, resolvedError)
-        })
-    }
-    args.push(responseCallback)
-    electron.webFrame[method](...args)
+  ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => {
+    new Promise(resolve =>
+      webFrame[method](...args, resolve)
+    ).then(result => {
+      return [null, result]
+    }, error => {
+      return [errorUtils.serialize(error)]
+    }).then(responseArgs => {
+      event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, ...responseArgs)
+    })
   })
 }