1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Handles uncaught exceptions thrown by extensions. By default this is to
6 // log an error message, but tests may override this behaviour.
7 var handler = function(message, e) {
8 console.error(message);
12 * Append the error description and stack trace to |message|.
14 * @param {string} message - The prefix of the error message.
15 * @param {Error|*} e - The thrown error object. This object is potentially
16 * unsafe, because it could be generated by an extension.
17 * @param {string=} priorStackTrace - The stack trace to be appended to the
18 * error message. This stack trace must not include stack frames of |e.stack|,
19 * because both stack traces are concatenated. Overlapping stack traces will
20 * confuse extension developers.
21 * @return {string} The formatted error message.
23 function formatErrorMessage(message, e, priorStackTrace) {
25 message += ': ' + safeErrorToString(e, false);
29 // If the stack was set, use it.
30 // |e.stack| could be void in the following common example:
31 // throw "Error message";
32 stack = $String.self(e && e.stack);
35 // If a stack is not provided, capture a stack trace.
36 if (!priorStackTrace && !stack)
37 stack = getStackTrace();
39 stack = filterExtensionStackTrace(stack);
41 message += '\n' + stack;
43 // If an asynchronouse stack trace was set, append it.
45 message += '\n' + priorStackTrace;
50 function filterExtensionStackTrace(stack) {
53 // Remove stack frames in the stack trace that weren't associated with the
54 // extension, to not confuse extension developers with internal details.
55 stack = $String.split(stack, '\n');
56 stack = $Array.filter(stack, function(line) {
57 return $String.indexOf(line, 'chrome-extension://') >= 0;
59 return $Array.join(stack, '\n');
62 function getStackTrace() {
64 $Error.captureStackTrace(e, getStackTrace);
68 function getExtensionStackTrace() {
69 return filterExtensionStackTrace(getStackTrace());
73 * Convert an object to a string.
75 * @param {Error|*} e - A thrown object (possibly user-supplied).
76 * @param {boolean=} omitType - Whether to try to serialize |e.message| instead
78 * @return {string} The error message.
80 function safeErrorToString(e, omitType) {
82 return $String.self(omitType && e.message || e);
84 // This error is exceptional and could be triggered by
85 // throw {toString: function() { throw 'Haha' } };
86 return '(cannot get error message)';
91 * Formats the error message and invokes the error handler.
93 * @param {string} message - Error message prefix.
94 * @param {Error|*} e - Thrown object.
95 * @param {string=} priorStackTrace - Error message suffix.
96 * @see formatErrorMessage
98 exports.handle = function(message, e, priorStackTrace) {
99 message = formatErrorMessage(message, e, priorStackTrace);
103 // |newHandler| A function which matches |handler|.
104 exports.setHandler = function(newHandler) {
105 handler = newHandler;
108 exports.getStackTrace = getStackTrace;
109 exports.getExtensionStackTrace = getExtensionStackTrace;
110 exports.safeErrorToString = safeErrorToString;