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

Side by Side Diff: extensions/renderer/resources/uncaught_exception_handler.js

Issue 482603002: Unify logic of stack trace generation for extension errors (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add $Error and $String.indexOf to safe builtins Created 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 // Handles uncaught exceptions thrown by extensions. By default this is to 5 // Handles uncaught exceptions thrown by extensions. By default this is to
6 // log an error message, but tests may override this behaviour. 6 // log an error message, but tests may override this behaviour.
7 var handler = function(message, e) { 7 var handler = function(message, e) {
8 console.error(message); 8 console.error(message);
9 }; 9 };
10 10
11 /** 11 /**
12 * Append the error description and stack trace to |message|. 12 * Append the error description and stack trace to |message|.
13 * 13 *
14 * @param {string} message - The prefix of the error message. 14 * @param {string} message - The prefix of the error message.
15 * @param {Error|*} e - The thrown error object. This object is potentially 15 * @param {Error|*} e - The thrown error object. This object is potentially
16 * unsafe, because it could be generated by an extension. 16 * unsafe, because it could be generated by an extension.
17 * @param {string=} stackTrace - The stack trace to be appended to the error 17 * @param {string=} priorStackTrace - The stack trace to be appended to the
18 * message. This stack trace must not include stack frames of |e.stack|. 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.
19 * @return {string} The formatted error message. 21 * @return {string} The formatted error message.
20 */ 22 */
21 function formatErrorMessage(message, e, stackTrace) { 23 function formatErrorMessage(message, e, priorStackTrace) {
not at google - send to devlin 2014/08/19 16:45:56 The diff on this file is super confusing, seems li
robwu 2014/08/19 17:35:57 This diff looks fine to me. I renamed the printSta
not at google - send to devlin 2014/08/19 17:54:38 I clicked on View which is supposed to show the di
22 // Append ": [error message]" 24 // Append ": [error message]"
23 if (e) { 25 if (e) {
24 try { 26 try {
25 // Append the toString() representation of |e| to the message. For 27 // Append the toString() representation of |e| to the message. For
26 // instances of Error, it looks like "Error: <message>". 28 // instances of Error, it looks like "Error: <message>".
27 message += ': ' + e; 29 message += ': ' + e;
28 } catch (e) { 30 } catch (e) {
29 // This could be triggered by 31 // This could be triggered by
30 // throw {toString: function() { throw 'Haha' } }; 32 // throw {toString: function() { throw 'Haha' } };
31 message += ': (cannot get error message)'; 33 message += ': (cannot get error message)';
32 } 34 }
33 } 35 }
34 36
35 var stack; 37 var stack;
36 try { 38 try {
37 // If the stack was set, use it. 39 // If the stack was set, use it.
38 // |e.stack| could be void in the following common example: 40 // |e.stack| could be void in the following common example:
39 // throw "Error message"; 41 // throw "Error message";
40 stack = $String.self(e && e.stack); 42 stack = $String.self(e && e.stack);
41 } catch (e) {} 43 } catch (e) {}
42 44
43 // If a stack is not provided, capture a stack trace. 45 // If a stack is not provided, capture a stack trace.
44 if (!stackTrace && !stack) 46 if (!priorStackTrace && !stack)
45 stack = getStackTrace(); 47 stack = getStackTrace();
46 48
47 stack = filterExtensionStackTrace(stack); 49 stack = filterExtensionStackTrace(stack);
48 if (stack) 50 if (stack)
49 message += '\n' + stack; 51 message += '\n' + stack;
50 52
51 // If an asynchronouse stack trace was set, append it. 53 // If an asynchronouse stack trace was set, append it.
52 if (stackTrace) 54 if (priorStackTrace)
53 message += '\n' + stackTrace; 55 message += '\n' + priorStackTrace;
54 56
55 return message; 57 return message;
56 } 58 }
57 59
58 function filterExtensionStackTrace(stack) { 60 function filterExtensionStackTrace(stack) {
59 if (!stack) 61 if (!stack)
60 return ''; 62 return '';
61 // Remove stack frames in the stack trace that weren't associated with the 63 // Remove stack frames in the stack trace that weren't associated with the
62 // extension, to not confuse extension developers with internal details. 64 // extension, to not confuse extension developers with internal details.
63 stack = $String.split(stack, '\n'); 65 stack = $String.split(stack, '\n');
64 stack = $Array.filter(stack, function(line) { 66 stack = $Array.filter(stack, function(line) {
65 return line.indexOf('chrome-extension://') >= 0; 67 return $String.indexOf(line, 'chrome-extension://') >= 0;
66 }); 68 });
67 return $Array.join(stack, '\n'); 69 return $Array.join(stack, '\n');
68 } 70 }
69 71
70 // Get a local reference to the captureStackTrace method to prevent extension
71 // code from interfering with our method.
72 var captureStackTrace = Error.captureStackTrace;
73 function getStackTrace() { 72 function getStackTrace() {
74 var e = {}; 73 var e = {};
75 captureStackTrace(e, getStackTrace); 74 $Error.captureStackTrace(e, getStackTrace);
76 return e.stack; 75 return e.stack;
77 } 76 }
78 77
79 function getExtensionStackTrace() { 78 function getExtensionStackTrace() {
80 return filterExtensionStackTrace(getStackTrace()); 79 return filterExtensionStackTrace(getStackTrace());
81 } 80 }
82 81
83 /** 82 /**
84 * Formats the error message and invokes the error handler. 83 * Formats the error message and invokes the error handler.
85 * 84 *
86 * @param {string} message - Error message prefix. 85 * @param {string} message - Error message prefix.
87 * @param {Error|*} e - Thrown object. 86 * @param {Error|*} e - Thrown object.
88 * @param {string=} stackTrace - Error message suffix. 87 * @param {string=} priorStackTrace - Error message suffix.
89 * @see formatErrorMessage 88 * @see formatErrorMessage
90 */ 89 */
91 exports.handle = function(message, e, stackTrace) { 90 exports.handle = function(message, e, priorStackTrace) {
92 message = formatErrorMessage(message, e, stackTrace); 91 message = formatErrorMessage(message, e, priorStackTrace);
93 handler(message, e); 92 handler(message, e);
94 }; 93 };
95 94
96 // |newHandler| A function which matches |handler|. 95 // |newHandler| A function which matches |handler|.
97 exports.setHandler = function(newHandler) { 96 exports.setHandler = function(newHandler) {
98 handler = newHandler; 97 handler = newHandler;
99 }; 98 };
100 99
101 exports.getStackTrace = getStackTrace; 100 exports.getStackTrace = getStackTrace;
102 exports.getExtensionStackTrace = getExtensionStackTrace; 101 exports.getExtensionStackTrace = getExtensionStackTrace;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698