Bug 1230194 Part 2 - Show stack for console evaluations that throw something, r=nchevobbe.

Differential Revision: https://phabricator.services.mozilla.com/D27827

--HG--
extra : rebase_source : 78bedd752592f1c8b6940b356c1ad43d9f1b6590
This commit is contained in:
Brian Hackett 2019-04-16 11:51:52 -10:00
Родитель b2e82bb4e7
Коммит 42e04a6b23
5 изменённых файлов: 85 добавлений и 19 удалений

Просмотреть файл

@ -20,6 +20,11 @@ EvaluationResult.propTypes = {
timestampsVisible: PropTypes.bool.isRequired,
serviceContainer: PropTypes.object,
maybeScrollToBottom: PropTypes.func,
open: PropTypes.bool,
};
EvaluationResult.defaultProps = {
open: false,
};
function EvaluationResult(props) {
@ -29,6 +34,7 @@ function EvaluationResult(props) {
serviceContainer,
timestampsVisible,
maybeScrollToBottom,
open,
} = props;
const {
@ -39,6 +45,7 @@ function EvaluationResult(props) {
id: messageId,
indent,
exceptionDocURL,
stacktrace,
frame,
timeStamp,
parameters,
@ -72,6 +79,7 @@ function EvaluationResult(props) {
const topLevelClasses = ["cm-s-mozilla"];
return Message({
dispatch,
source,
type,
level,
@ -81,6 +89,9 @@ function EvaluationResult(props) {
messageId,
serviceContainer,
exceptionDocURL,
stacktrace,
collapsible: Array.isArray(stacktrace),
open,
frame,
timeStamp,
parameters,

Просмотреть файл

@ -293,6 +293,7 @@ function transformEvaluationResultPacket(packet) {
errorMessageName,
exceptionDocURL,
exception,
exceptionStack,
frame,
result,
helperResult,
@ -328,6 +329,7 @@ function transformEvaluationResultPacket(packet) {
parameters: [parameter],
errorMessageName,
exceptionDocURL,
stacktrace: exceptionStack,
frame,
timeStamp,
notes,

Просмотреть файл

@ -1010,7 +1010,7 @@ WebConsoleActor.prototype =
const helperResult = evalInfo.helperResult;
let result, errorDocURL, errorMessage, errorNotes = null, errorGrip = null,
frame = null, awaitResult, errorMessageName;
frame = null, awaitResult, errorMessageName, exceptionStack;
if (evalResult) {
if ("return" in evalResult) {
result = evalResult.return;
@ -1029,6 +1029,21 @@ WebConsoleActor.prototype =
const error = evalResult.throw;
errorGrip = this.createValueGrip(error);
exceptionStack = this.prepareStackForRemote(evalResult.stack);
if (exceptionStack) {
// Set the frame based on the topmost stack frame for the exception.
const {
filename: source,
sourceId,
lineNumber: line,
columnNumber: column,
} = exceptionStack[0];
frame = { source, sourceId, line, column };
exceptionStack = WebConsoleUtils.removeFramesAboveDebuggerEval(exceptionStack);
}
errorMessage = String(error);
if (typeof error === "object" && error !== null) {
try {
@ -1132,6 +1147,7 @@ WebConsoleActor.prototype =
exception: errorGrip,
exceptionMessage: this._createStringGrip(errorMessage),
exceptionDocURL: errorDocURL,
exceptionStack,
errorMessageName,
frame,
helperResult: helperResult,
@ -1465,6 +1481,36 @@ WebConsoleActor.prototype =
return actor ? actor.actorID : null;
},
/**
* Prepare a SavedFrame stack to be sent to the client.
*
* @param SavedFrame errorStack
* Stack for an error we need to send to the client.
* @return object
* The object you can send to the remote client.
*/
prepareStackForRemote(errorStack) {
// Convert stack objects to the JSON attributes expected by client code
// Bug 1348885: If the global from which this error came from has been
// nuked, stack is going to be a dead wrapper.
if (!errorStack || (Cu && Cu.isDeadWrapper(errorStack))) {
return null;
}
const stack = [];
let s = errorStack;
while (s) {
stack.push({
filename: s.source,
sourceId: this.getActorIdForInternalSourceId(s.sourceId),
lineNumber: s.line,
columnNumber: s.column,
functionName: s.functionDisplayName,
});
s = s.parent;
}
return stack;
},
/**
* Prepare an nsIScriptError to be sent to the client.
*
@ -1474,24 +1520,7 @@ WebConsoleActor.prototype =
* The object you can send to the remote client.
*/
preparePageErrorForRemote: function(pageError) {
let stack = null;
// Convert stack objects to the JSON attributes expected by client code
// Bug 1348885: If the global from which this error came from has been
// nuked, stack is going to be a dead wrapper.
if (pageError.stack && !Cu.isDeadWrapper(pageError.stack)) {
stack = [];
let s = pageError.stack;
while (s !== null) {
stack.push({
filename: s.source,
sourceId: this.getActorIdForInternalSourceId(s.sourceId),
lineNumber: s.line,
columnNumber: s.column,
functionName: s.functionDisplayName,
});
s = s.parent;
}
}
const stack = this.prepareStackForRemote(pageError.stack);
let lineText = pageError.sourceLine;
if (lineText && lineText.length > DebuggerServer.LONG_STRING_INITIAL_LENGTH) {
lineText = lineText.substr(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH);

Просмотреть файл

@ -193,6 +193,29 @@ var WebConsoleUtils = {
return null;
}
},
/**
* Remove any frames in a stack that are above a debugger-triggered evaluation
* and will correspond with devtools server code, which we never want to show
* to the user.
*
* @param array stack
* An array of frames, with the topmost first, and each of which has a
* 'filename' property.
* @return array
* An array of stack frames with any devtools server frames removed.
* The original array is not modified.
*/
removeFramesAboveDebuggerEval(stack) {
// Remove any frames for server code above the debugger eval.
const evalIndex = stack.findIndex(({ filename }) => {
return filename == "debugger eval code";
});
if (evalIndex != -1) {
return stack.slice(0, evalIndex + 1);
}
return stack;
},
};
exports.WebConsoleUtils = WebConsoleUtils;

Просмотреть файл

@ -49,6 +49,7 @@ const webconsoleSpecPrototype = {
exception: Option(0, "nullable:json"),
exceptionMessage: Option(0, "nullable:string"),
exceptionDocURL: Option(0, "nullable:string"),
exceptionStack: Option(0, "nullable:json"),
frame: Option(0, "nullable:json"),
helperResult: Option(0, "nullable:json"),
input: Option(0, "nullable:string"),