[inspector] Add exception caught/uncaught status to protocol
This adds information about an exception's caught/uncaught status to the Runtime.paused event in the data parameter: { "method": "Debugger.paused", "params": { "callFrames": [ [...] ], "data": { "description": "666", "type": "number", "uncaught": true, <--- "value": 666 }, "hitBreakpoints": [], "reason": "exception" } } BUG=v8:5530 Review-Url: https://codereview.chromium.org/2488733003 Cr-Commit-Position: refs/heads/master@{#40875}
This commit is contained in:
parent
fa9e404bf0
commit
fab116be0e
@ -1078,7 +1078,8 @@ void V8DebuggerAgentImpl::didParseSource(
|
||||
|
||||
V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::Value> exception,
|
||||
const std::vector<String16>& hitBreakpoints, bool isPromiseRejection) {
|
||||
const std::vector<String16>& hitBreakpoints, bool isPromiseRejection,
|
||||
bool isUncaught) {
|
||||
JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1);
|
||||
JavaScriptCallFrame* topCallFrame =
|
||||
!callFrames.empty() ? callFrames.begin()->get() : nullptr;
|
||||
@ -1120,7 +1121,12 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(
|
||||
std::unique_ptr<protocol::Runtime::RemoteObject> obj;
|
||||
injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
|
||||
&obj);
|
||||
m_breakAuxData = obj ? obj->serialize() : nullptr;
|
||||
if (obj) {
|
||||
m_breakAuxData = obj->serialize();
|
||||
m_breakAuxData->setBoolean("uncaught", isUncaught);
|
||||
} else {
|
||||
m_breakAuxData = nullptr;
|
||||
}
|
||||
// m_breakAuxData might be null after this.
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
|
||||
SkipPauseRequest didPause(v8::Local<v8::Context>,
|
||||
v8::Local<v8::Value> exception,
|
||||
const std::vector<String16>& hitBreakpoints,
|
||||
bool isPromiseRejection);
|
||||
bool isPromiseRejection, bool isUncaught);
|
||||
void didContinue();
|
||||
void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
|
||||
void willExecuteScript(int scriptId);
|
||||
|
@ -486,7 +486,7 @@ void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext,
|
||||
v8::Local<v8::Object> executionState,
|
||||
v8::Local<v8::Value> exception,
|
||||
v8::Local<v8::Array> hitBreakpointNumbers,
|
||||
bool isPromiseRejection) {
|
||||
bool isPromiseRejection, bool isUncaught) {
|
||||
// Don't allow nested breaks.
|
||||
if (m_runningNestedMessageLoop) return;
|
||||
|
||||
@ -509,7 +509,7 @@ void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext,
|
||||
m_pausedContext = pausedContext;
|
||||
m_executionState = executionState;
|
||||
V8DebuggerAgentImpl::SkipPauseRequest result = agent->didPause(
|
||||
pausedContext, exception, breakpointIds, isPromiseRejection);
|
||||
pausedContext, exception, breakpointIds, isPromiseRejection, isUncaught);
|
||||
if (result == V8DebuggerAgentImpl::RequestNoSkip) {
|
||||
m_runningNestedMessageLoop = true;
|
||||
int groupId = getGroupId(pausedContext);
|
||||
@ -595,14 +595,19 @@ void V8Debugger::handleV8DebugEvent(
|
||||
wrapUnique(new V8DebuggerScript(m_isolate, script, inLiveEditScope)),
|
||||
event == v8::AfterCompile);
|
||||
} else if (event == v8::Exception) {
|
||||
v8::Local<v8::Context> context = debuggerContext();
|
||||
v8::Local<v8::Object> eventData = eventDetails.GetEventData();
|
||||
v8::Local<v8::Value> exception =
|
||||
callInternalGetterFunction(eventData, "exception");
|
||||
v8::Local<v8::Value> promise =
|
||||
callInternalGetterFunction(eventData, "promise");
|
||||
bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject();
|
||||
v8::Local<v8::Value> uncaught =
|
||||
callInternalGetterFunction(eventData, "uncaught");
|
||||
bool isUncaught = uncaught->BooleanValue(context).FromJust();
|
||||
handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
|
||||
exception, v8::Local<v8::Array>(), isPromiseRejection);
|
||||
exception, v8::Local<v8::Array>(), isPromiseRejection,
|
||||
isUncaught);
|
||||
} else if (event == v8::Break) {
|
||||
v8::Local<v8::Value> argv[] = {eventDetails.GetEventData()};
|
||||
v8::Local<v8::Value> hitBreakpoints =
|
||||
|
@ -107,7 +107,8 @@ class V8Debugger {
|
||||
v8::Local<v8::Object> executionState,
|
||||
v8::Local<v8::Value> exception,
|
||||
v8::Local<v8::Array> hitBreakpoints,
|
||||
bool isPromiseRejection = false);
|
||||
bool isPromiseRejection = false,
|
||||
bool isUncaught = false);
|
||||
static void v8DebugEventCallback(const v8::DebugInterface::EventDetails&);
|
||||
v8::Local<v8::Value> callInternalGetterFunction(v8::Local<v8::Object>,
|
||||
const char* functionName);
|
||||
|
@ -0,0 +1,5 @@
|
||||
Check that inspector correctly passes caught/uncaught information.
|
||||
paused in throwCaught
|
||||
uncaught: false
|
||||
paused in throwUncaught
|
||||
uncaught: true
|
25
test/inspector/debugger/caught-uncaught-exceptions.js
Normal file
25
test/inspector/debugger/caught-uncaught-exceptions.js
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
print("Check that inspector correctly passes caught/uncaught information.");
|
||||
|
||||
InspectorTest.addScript(
|
||||
`function throwCaught() { try { throw new Error(); } catch (_) {} }
|
||||
function throwUncaught() { throw new Error(); }
|
||||
function schedule(f) { setTimeout(f, 0); }
|
||||
`);
|
||||
|
||||
Protocol.Debugger.enable();
|
||||
|
||||
Protocol.Debugger.setPauseOnExceptions({ "state": "all" });
|
||||
Protocol.Debugger.onPaused(message => {
|
||||
InspectorTest.log("paused in " + message.params.callFrames[0].functionName);
|
||||
InspectorTest.log("uncaught: " + message.params.data.uncaught);
|
||||
Protocol.Debugger.resume();
|
||||
});
|
||||
|
||||
Protocol.Runtime.evaluate({ "expression": "schedule(throwCaught);" })
|
||||
.then(() => Protocol.Runtime.evaluate(
|
||||
{ "expression": "schedule(throwUncaught);" }))
|
||||
.then(() => InspectorTest.completeTest());
|
Loading…
Reference in New Issue
Block a user