зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b2e82bb4e7
Коммит
42e04a6b23
|
@ -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"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче