OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var lastError = require('lastError'); | 5 var lastError = require('lastError'); |
6 var logging = requireNative('logging'); | 6 var logging = requireNative('logging'); |
7 var natives = requireNative('sendRequest'); | 7 var natives = requireNative('sendRequest'); |
8 var processNatives = requireNative('process'); | 8 var processNatives = requireNative('process'); |
9 var validate = require('schemaUtils').validate; | 9 var validate = require('schemaUtils').validate; |
10 | 10 |
11 // All outstanding requests from sendRequest(). | 11 // All outstanding requests from sendRequest(). |
12 var requests = {}; | 12 var requests = {}; |
13 | 13 |
14 // Used to prevent double Activity Logging for API calls that use both custom | 14 // Used to prevent double Activity Logging for API calls that use both custom |
15 // bindings and ExtensionFunctions (via sendRequest). | 15 // bindings and ExtensionFunctions (via sendRequest). |
16 var calledSendRequest = false; | 16 var calledSendRequest = false; |
17 | 17 |
18 // Runs a user-supplied callback safely. | 18 // Runs a user-supplied callback safely. |
19 function safeCallbackApply(name, request, callback, args) { | 19 function safeCallbackApply(name, request, callback, args) { |
20 try { | 20 try { |
21 callback.apply(request, args); | 21 $Function.apply(callback, request, args); |
22 } catch (e) { | 22 } catch (e) { |
23 var errorMessage = "Error in response to " + name + ": " + e; | 23 var errorMessage = "Error in response to " + name + ": " + e; |
24 if (request.stack && request.stack != '') | 24 if (request.stack && request.stack != '') |
25 errorMessage += "\n" + request.stack; | 25 errorMessage += "\n" + request.stack; |
26 console.error(errorMessage); | 26 console.error(errorMessage); |
27 } | 27 } |
28 } | 28 } |
29 | 29 |
30 // Callback handling. | 30 // Callback handling. |
31 function handleResponse(requestId, name, success, responseList, error) { | 31 function handleResponse(requestId, name, success, responseList, error) { |
32 // The chrome objects we will set lastError on. Really we should only be | 32 // The chrome objects we will set lastError on. Really we should only be |
33 // setting this on the callback's chrome object, but set on ours too since | 33 // setting this on the callback's chrome object, but set on ours too since |
34 // it's conceivable that something relies on that. | 34 // it's conceivable that something relies on that. |
35 var chromesForLastError = [chrome]; | 35 var chromesForLastError = [chrome]; |
36 | 36 |
37 try { | 37 try { |
38 var request = requests[requestId]; | 38 var request = requests[requestId]; |
39 logging.DCHECK(request != null); | 39 logging.DCHECK(request != null); |
40 | 40 |
41 // lastError needs to be set on the caller's chrome object no matter what, | 41 // lastError needs to be set on the caller's chrome object no matter what, |
42 // though chances are it's the same as ours (it will be different when | 42 // though chances are it's the same as ours (it will be different when |
43 // calling API methods on other contexts). | 43 // calling API methods on other contexts). |
44 if (request.callback) { | 44 if (request.callback) { |
45 var chromeForCallback = natives.GetGlobal(request.callback).chrome; | 45 var chromeForCallback = natives.GetGlobal(request.callback).chrome; |
46 if (chromeForCallback != chrome) | 46 if (chromeForCallback != chrome) |
47 chromesForLastError.push(chromeForCallback); | 47 $Array.push(chromesForLastError, chromeForCallback); |
48 } | 48 } |
49 | 49 |
50 $Array.forEach(chromesForLastError, function(c) {lastError.clear(c)}); | 50 $Array.forEach(chromesForLastError, function(c) {lastError.clear(c)}); |
51 if (!success) { | 51 if (!success) { |
52 if (!error) | 52 if (!error) |
53 error = "Unknown error."; | 53 error = "Unknown error."; |
54 $Array.forEach(chromesForLastError, function(c) { | 54 $Array.forEach(chromesForLastError, function(c) { |
55 lastError.set(name, error, request.stack, c) | 55 lastError.set(name, error, request.stack, c) |
56 }); | 56 }); |
57 } | 57 } |
58 | 58 |
59 if (request.customCallback) { | 59 if (request.customCallback) { |
60 safeCallbackApply(name, | 60 safeCallbackApply(name, |
61 request, | 61 request, |
62 request.customCallback, | 62 request.customCallback, |
63 [name, request].concat(responseList)); | 63 $Array.concat([name, request], responseList)); |
64 } | 64 } |
65 | 65 |
66 if (request.callback) { | 66 if (request.callback) { |
67 // Validate callback in debug only -- and only when the | 67 // Validate callback in debug only -- and only when the |
68 // caller has provided a callback. Implementations of api | 68 // caller has provided a callback. Implementations of api |
69 // calls may not return data if they observe the caller | 69 // calls may not return data if they observe the caller |
70 // has not provided a callback. | 70 // has not provided a callback. |
71 if (logging.DCHECK_IS_ON() && !error) { | 71 if (logging.DCHECK_IS_ON() && !error) { |
72 if (!request.callbackSchema.parameters) | 72 if (!request.callbackSchema.parameters) |
73 throw new Error(name + ": no callback schema defined"); | 73 throw new Error(name + ": no callback schema defined"); |
74 validate(responseList, request.callbackSchema.parameters); | 74 validate(responseList, request.callbackSchema.parameters); |
75 } | 75 } |
76 safeCallbackApply(name, request, request.callback, responseList); | 76 safeCallbackApply(name, request, request.callback, responseList); |
77 } | 77 } |
78 } finally { | 78 } finally { |
79 delete requests[requestId]; | 79 delete requests[requestId]; |
80 $Array.forEach(chromesForLastError, function(c) {lastError.clear(c)}); | 80 $Array.forEach(chromesForLastError, function(c) {lastError.clear(c)}); |
81 } | 81 } |
82 }; | 82 }; |
83 | 83 |
84 function getExtensionStackTrace(call_name) { | 84 function getExtensionStackTrace(call_name) { |
85 var stack = new Error().stack.split('\n'); | 85 var stack = $String.split(new Error().stack, '\n'); |
86 | 86 |
87 // Remove stack frames before and after that weren't associated with the | 87 // Remove stack frames before and after that weren't associated with the |
88 // extension. | 88 // extension. |
89 var id = processNatives.GetExtensionId(); | 89 var id = processNatives.GetExtensionId(); |
90 while (stack.length > 0 && stack[0].indexOf(id) == -1) | 90 while (stack.length > 0 && stack[0].indexOf(id) == -1) |
91 stack.shift(); | 91 stack.shift(); |
92 while (stack.length > 0 && stack[stack.length - 1].indexOf(id) == -1) | 92 while (stack.length > 0 && stack[stack.length - 1].indexOf(id) == -1) |
93 stack.pop(); | 93 stack.pop(); |
94 | 94 |
95 return stack.join('\n'); | 95 return stack.join('\n'); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 function clearCalledSendRequest() { | 156 function clearCalledSendRequest() { |
157 calledSendRequest = false; | 157 calledSendRequest = false; |
158 } | 158 } |
159 | 159 |
160 exports.sendRequest = sendRequest; | 160 exports.sendRequest = sendRequest; |
161 exports.getCalledSendRequest = getCalledSendRequest; | 161 exports.getCalledSendRequest = getCalledSendRequest; |
162 exports.clearCalledSendRequest = clearCalledSendRequest; | 162 exports.clearCalledSendRequest = clearCalledSendRequest; |
163 | 163 |
164 // Called by C++. | 164 // Called by C++. |
165 exports.handleResponse = handleResponse; | 165 exports.handleResponse = handleResponse; |
OLD | NEW |