diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 149b208b409d..7bbc019b6d72 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -69,7 +69,9 @@ unwrapArgs = (sender, args) -> rendererReleased = true ret = -> - throw new Error('Calling a callback of released renderer view') if rendererReleased + if rendererReleased + throw new Error("Attempting to call a function in a renderer window + that has been closed or released. Function provided here: #{meta.id}.") sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index 8f5eb62916c0..a9e9c7b1228f 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -11,6 +11,20 @@ class CallbacksRegistry add: (callback) -> id = Math.random().toString() + + # Capture the location of the function and put it in the ID string, + # so that release errors can be tracked down easily. + regexp = /at (.*)/gi + stackString = (new Error).stack + + while (match = regexp.exec(stackString)) isnt null + [x, location] = match + continue if location.indexOf('(native)') isnt -1 + continue if location.indexOf('atom.asar') isnt -1 + [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) + id = "#{filenameAndLine} (#{id})" + break + @callbacks[id] = callback id