Throw custom error when remote object is missing from registry
authorKevin Sawicki <kevinsawicki@gmail.com>
Thu, 17 Nov 2016 17:55:13 +0000 (09:55 -0800)
committerKevin Sawicki <kevinsawicki@gmail.com>
Thu, 17 Nov 2016 17:55:13 +0000 (09:55 -0800)
lib/browser/objects-registry.js
lib/browser/rpc-server.js

index 1917c65..aeaf535 100644 (file)
@@ -41,7 +41,8 @@ class ObjectsRegistry {
 
   // Get an object according to its ID.
   get (id) {
-    return this.storage[id].object
+    const pointer = this.storage[id]
+    if (pointer != null) return pointer.object
   }
 
   // Dereference an object according to its ID.
index e3f731c..03eed56 100644 (file)
@@ -139,6 +139,12 @@ const exceptionToMeta = function (error) {
   }
 }
 
+const throwRPCError = function (message) {
+  const error = new Error(message)
+  error.code = 'EBADRPC'
+  throw error
+}
+
 // Convert array of meta data from renderer into array of real values.
 const unwrapArgs = function (sender, args) {
   const metaToValue = function (meta) {
@@ -277,6 +283,10 @@ ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
     args = unwrapArgs(event.sender, args)
     let constructor = objectsRegistry.get(id)
 
+    if (constructor == null) {
+      throwRPCError(`Cannot call constructor on missing remote object ${id}`)
+    }
+
     // Call new with array of arguments.
     // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
     let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
@@ -290,6 +300,11 @@ ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
   try {
     args = unwrapArgs(event.sender, args)
     let func = objectsRegistry.get(id)
+
+    if (func == null) {
+      throwRPCError(`Cannot call function on missing remote object ${id}`)
+    }
+
     callFunction(event, func, global, args)
   } catch (error) {
     event.returnValue = exceptionToMeta(error)
@@ -299,9 +314,14 @@ ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
 ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
   try {
     args = unwrapArgs(event.sender, args)
-    let constructor = objectsRegistry.get(id)[method]
+    let object = objectsRegistry.get(id)
+
+    if (object == null) {
+      throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
+    }
 
     // Call new with array of arguments.
+    let constructor = object[method]
     let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
     event.returnValue = valueToMeta(event.sender, obj)
   } catch (error) {
@@ -313,6 +333,11 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
   try {
     args = unwrapArgs(event.sender, args)
     let obj = objectsRegistry.get(id)
+
+    if (obj == null) {
+      throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
+    }
+
     callFunction(event, obj[method], obj, args)
   } catch (error) {
     event.returnValue = exceptionToMeta(error)
@@ -322,6 +347,11 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
 ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) {
   try {
     let obj = objectsRegistry.get(id)
+
+    if (obj == null) {
+      throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
+    }
+
     obj[name] = value
     event.returnValue = null
   } catch (error) {