Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: chrome/browser/resources/google_now/utility.js

Issue 22518002: Incremental changes in error reporting (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cosmetics Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/google_now/utility.js
diff --git a/chrome/browser/resources/google_now/utility.js b/chrome/browser/resources/google_now/utility.js
index 12e9f93dd21b49f9540864992e4edf63c5d5fdbd..57db70678714ed73cfce7492e09edc7741411d12 100644
--- a/chrome/browser/resources/google_now/utility.js
+++ b/chrome/browser/resources/google_now/utility.js
@@ -20,12 +20,15 @@ var NOTIFICATION_CARDS_URL = localStorage['server_url'];
var DEBUG_MODE = localStorage['debug_mode'];
/**
- * Shows a message popup in debug mode.
- * @param {string} message Diagnostic message.
+ * Builds an error object with a message that may be sent to the server.
+ * @param {string} message Error message. This message may be sent to the
+ * server.
+ * @return {Error} Error object.
*/
-function debugAlert(message) {
- if (DEBUG_MODE)
- alert(message);
+function buildErrorWithMessageForServer(message) {
+ var error = new Error(message);
+ error.canSendMessageToServer = true;
+ return error;
}
/**
@@ -36,7 +39,7 @@ function debugAlert(message) {
*/
function verify(condition, message) {
if (!condition)
- throw new Error('\nASSERT: ' + message);
+ throw buildErrorWithMessageForServer('ASSERT: ' + message);
}
/**
@@ -105,12 +108,8 @@ function buildTaskManager(areConflicting) {
*/
function checkInInstrumentedCallback() {
if (!isInInstrumentedCallback) {
- // Cannot use verify() since no one will catch the exception.
- // This check will detect bugs at the development stage, and is very
- // unlikely to be seen by users.
- var error = 'Not in instrumented callback: ' + new Error().stack;
- console.error(error);
- debugAlert(error);
+ reportError(buildErrorWithMessageForServer(
+ 'Not in instrumented callback'));
}
}
@@ -196,29 +195,45 @@ function buildTaskManager(areConflicting) {
/**
* Sends an error report to the server.
- * @param {Error} error Error to report.
+ * @param {Error} error Error to send.
*/
function sendErrorReport(error) {
- var filteredStack = error.stack.replace(/.*\n/, '\n');
+ var filteredStack = error.canSendMessageToServer ?
+ error.stack : error.stack.replace(/.*\n/, '(message removed)\n');
var file;
var line;
- var topFrameMatches = filteredStack.match(/\(.*\)/);
- // topFrameMatches's example:
- // (chrome-extension://pmofbkohncoogjjhahejjfbppikbjigm/utility.js:308:19)
- var crashLocation = topFrameMatches && topFrameMatches[0];
- if (crashLocation) {
- var topFrameElements =
- crashLocation.substring(1, crashLocation.length - 1).split(':');
- // topFrameElements for the above example will look like:
- // [0] chrome-extension
- // [1] //pmofbkohncoogjjhahejjfbppikbjigm/utility.js
- // [2] 308
- // [3] 19
+ var topFrameLineMatch = filteredStack.match(/\n at .*\n/);
+ var topFrame = topFrameLineMatch && topFrameLineMatch[0];
+ if (topFrame) {
+ // Examples of a frame:
+ // 1. '\n at someFunction (chrome-extension://
+ // pmofbkohncoogjjhahejjfbppikbjigm/background.js:915:15)\n'
+ // 2. '\n at chrome-extension://pmofbkohncoogjjhahejjfbppikbjigm/
+ // utility.js:269:18\n'
+ // 3. '\n at Function.target.(anonymous function) (extensions::
+ // SafeBuiltins:19:14)\n'
+ // 4. '\n at Event.dispatchToListener (event_bindings:382:22)\n'
+ var errorLocation;
+ // Find the the parentheses at the end of the line, if any.
+ var parenthesesMatch = topFrame.match(/\(.*\)\n/);
+ if (parenthesesMatch && parenthesesMatch[0]) {
+ errorLocation =
+ parenthesesMatch[0].substring(1, parenthesesMatch[0].length - 2);
+ } else {
+ errorLocation = topFrame;
+ }
+
+ var topFrameElements = errorLocation.split(':');
+ // topFrameElements is an array that ends like:
+ // [N-3] //pmofbkohncoogjjhahejjfbppikbjigm/utility.js
+ // [N-2] 308
+ // [N-1] 19
if (topFrameElements.length >= 3) {
- file = topFrameElements[0] + ':' + topFrameElements[1];
- line = topFrameElements[2];
+ file = topFrameElements[topFrameElements.length - 3];
+ line = topFrameElements[topFrameElements.length - 2];
}
}
+
var requestParameters =
'error=' + encodeURIComponent(error.name) +
'&script=' + encodeURIComponent(file) +
@@ -233,6 +248,24 @@ function buildTaskManager(areConflicting) {
}
/**
+ * Reports an error to the server and the user, as appropriate.
+ * @param {Error} error Error to report.
+ */
+ function reportError(error) {
+ var message = 'Critical error:\n' + error.stack;
+ console.error(message);
arv (Not doing code reviews) 2013/08/12 21:31:30 console.error(error) also prints the stack. If yo
vadimt 2013/08/12 23:32:22 Couple of reasons why this would be not ideal: 1.
+ if (!errorReported) {
+ errorReported = true;
+ chrome.metricsPrivate.getIsCrashReportingEnabled(function(isEnabled) {
+ if (isEnabled)
skare_ 2013/08/12 20:47:14 just checking, isEnabled == false and DEBUG_MODE =
vadimt 2013/08/12 20:57:39 Correct.
+ sendErrorReport(error);
+ if (DEBUG_MODE)
+ alert(message);
+ });
+ }
+ }
+
+ /**
* Unique ID of the next callback.
* @type {number}
*/
@@ -284,16 +317,7 @@ function buildTaskManager(areConflicting) {
'Instrumented callback is not instrumented upon exit');
isInInstrumentedCallback = false;
} catch (error) {
- var message = 'Uncaught exception:\n' + error.stack;
- console.error(message);
- if (!errorReported) {
- errorReported = true;
- chrome.metricsPrivate.getIsCrashReportingEnabled(function(isEnabled) {
- if (isEnabled)
- sendErrorReport(error);
- });
- debugAlert(message);
- }
+ reportError(error);
}
};
}
@@ -315,9 +339,10 @@ function buildTaskManager(areConflicting) {
// the original function.
var callback = arguments[callbackParameter];
if (typeof callback != 'function') {
- debugAlert('Argument ' + callbackParameter + ' of ' +
- functionIdentifierParts.join('.') + '.' + functionName +
- ' is not a function');
+ reportError(buildErrorWithMessageForServer(
+ 'Argument ' + callbackParameter + ' of ' +
+ functionIdentifierParts.join('.') + '.' + functionName +
+ ' is not a function'));
}
arguments[callbackParameter] = wrapCallback(
callback, functionName == 'addListener');
@@ -346,6 +371,11 @@ function buildTaskManager(areConflicting) {
var instrumentedContainer = instrumented;
functionIdentifierParts.map(function(fragment) {
chromeContainer = chromeContainer[fragment];
+ if (!chromeContainer) {
+ reportError(buildErrorWithMessageForServer(
+ 'Cannot instrument ' + functionIdentifier));
+ }
+
if (!(fragment in instrumentedContainer))
instrumentedContainer[fragment] = {};
@@ -353,9 +383,10 @@ function buildTaskManager(areConflicting) {
});
var targetFunction = chromeContainer[functionName];
-
- if (!targetFunction)
- debugAlert('Cannot instrument ' + functionName);
+ if (!targetFunction) {
+ reportError(buildErrorWithMessageForServer(
+ 'Cannot instrument ' + functionIdentifier));
+ }
instrumentedContainer[functionName] = createInstrumentedFunction(
functionIdentifierParts,
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698