| Index: extensions/renderer/resources/uncaught_exception_handler.js
|
| diff --git a/extensions/renderer/resources/uncaught_exception_handler.js b/extensions/renderer/resources/uncaught_exception_handler.js
|
| index a3709b58f3c0f6c0e9de5d31e88e2381c5e167c5..f87efbc995c50ad7a8ceafcbdbcf081c2a193a93 100644
|
| --- a/extensions/renderer/resources/uncaught_exception_handler.js
|
| +++ b/extensions/renderer/resources/uncaught_exception_handler.js
|
| @@ -4,18 +4,107 @@
|
|
|
| // Handles uncaught exceptions thrown by extensions. By default this is to
|
| // log an error message, but tests may override this behaviour.
|
| -
|
| var handler = function(message, e) {
|
| console.error(message);
|
| };
|
|
|
| -// |message| The message associated with the error.
|
| -// |e| The object that was thrown.
|
| -exports.handle = function(message, e) {
|
| +/**
|
| + * Append the error description and stack trace to |message|.
|
| + *
|
| + * @param {string} message - The prefix of the error message.
|
| + * @param {Error|*} e - The thrown error object. This object is potentially
|
| + * unsafe, because it could be generated by an extension.
|
| + * @param {string=} priorStackTrace - The stack trace to be appended to the
|
| + * error message. This stack trace must not include stack frames of |e.stack|,
|
| + * because both stack traces are concatenated. Overlapping stack traces will
|
| + * confuse extension developers.
|
| + * @return {string} The formatted error message.
|
| + */
|
| +function formatErrorMessage(message, e, priorStackTrace) {
|
| + if (e)
|
| + message += ': ' + safeErrorToString(e, false);
|
| +
|
| + var stack;
|
| + try {
|
| + // If the stack was set, use it.
|
| + // |e.stack| could be void in the following common example:
|
| + // throw "Error message";
|
| + stack = $String.self(e && e.stack);
|
| + } catch (e) {}
|
| +
|
| + // If a stack is not provided, capture a stack trace.
|
| + if (!priorStackTrace && !stack)
|
| + stack = getStackTrace();
|
| +
|
| + stack = filterExtensionStackTrace(stack);
|
| + if (stack)
|
| + message += '\n' + stack;
|
| +
|
| + // If an asynchronouse stack trace was set, append it.
|
| + if (priorStackTrace)
|
| + message += '\n' + priorStackTrace;
|
| +
|
| + return message;
|
| +}
|
| +
|
| +function filterExtensionStackTrace(stack) {
|
| + if (!stack)
|
| + return '';
|
| + // Remove stack frames in the stack trace that weren't associated with the
|
| + // extension, to not confuse extension developers with internal details.
|
| + stack = $String.split(stack, '\n');
|
| + stack = $Array.filter(stack, function(line) {
|
| + return $String.indexOf(line, 'chrome-extension://') >= 0;
|
| + });
|
| + return $Array.join(stack, '\n');
|
| +}
|
| +
|
| +function getStackTrace() {
|
| + var e = {};
|
| + $Error.captureStackTrace(e, getStackTrace);
|
| + return e.stack;
|
| +}
|
| +
|
| +function getExtensionStackTrace() {
|
| + return filterExtensionStackTrace(getStackTrace());
|
| +}
|
| +
|
| +/**
|
| + * Convert an object to a string.
|
| + *
|
| + * @param {Error|*} e - A thrown object (possibly user-supplied).
|
| + * @param {boolean=} omitType - Whether to try to serialize |e.message| instead
|
| + * of |e.toString()|.
|
| + * @return {string} The error message.
|
| + */
|
| +function safeErrorToString(e, omitType) {
|
| + try {
|
| + return $String.self(omitType && e.message || e);
|
| + } catch (e) {
|
| + // This error is exceptional and could be triggered by
|
| + // throw {toString: function() { throw 'Haha' } };
|
| + return '(cannot get error message)';
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Formats the error message and invokes the error handler.
|
| + *
|
| + * @param {string} message - Error message prefix.
|
| + * @param {Error|*} e - Thrown object.
|
| + * @param {string=} priorStackTrace - Error message suffix.
|
| + * @see formatErrorMessage
|
| + */
|
| +exports.handle = function(message, e, priorStackTrace) {
|
| + message = formatErrorMessage(message, e, priorStackTrace);
|
| handler(message, e);
|
| };
|
|
|
| -// |newHandler| A function which matches |exports.handle|.
|
| +// |newHandler| A function which matches |handler|.
|
| exports.setHandler = function(newHandler) {
|
| handler = newHandler;
|
| };
|
| +
|
| +exports.getStackTrace = getStackTrace;
|
| +exports.getExtensionStackTrace = getExtensionStackTrace;
|
| +exports.safeErrorToString = safeErrorToString;
|
|
|