[inspector] Report exceptionMetaData for Runtime#getExceptionDetails
The ExceptionDetails structure allows the association of requests and issues with JavaScript errors. These are currently only reported when an exception goes through `Runtime#exceptionThrown`, but we also want the metadata available when the ExceptionDetails are requested explicitly for any Error object. R=bmeurer@chromium.org Bug: chromium:1280141 Change-Id: I1b1514207b9e146fda3452c3f7991cd7dc9a387b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3477098 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/main@{#79199}
This commit is contained in:
parent
6892cdf8ae
commit
17536f94d6
@ -396,23 +396,11 @@ V8ConsoleMessage::getAssociatedExceptionData(
|
||||
|
||||
v8::Isolate* isolate = inspector->isolate();
|
||||
v8::HandleScope handles(isolate);
|
||||
v8::Local<v8::Context> context;
|
||||
if (!inspector->exceptionMetaDataContext().ToLocal(&context)) return nullptr;
|
||||
v8::MaybeLocal<v8::Value> maybe_exception = m_arguments[0]->Get(isolate);
|
||||
v8::Local<v8::Value> exception;
|
||||
if (!maybe_exception.ToLocal(&exception)) return nullptr;
|
||||
|
||||
v8::MaybeLocal<v8::Object> maybe_data =
|
||||
inspector->getAssociatedExceptionData(exception);
|
||||
v8::Local<v8::Object> data;
|
||||
if (!maybe_data.ToLocal(&data)) return nullptr;
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
v8::MicrotasksScope microtasksScope(isolate,
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
v8::Context::Scope contextScope(context);
|
||||
std::unique_ptr<protocol::DictionaryValue> jsonObject;
|
||||
objectToProtocolValue(context, data, 2, &jsonObject);
|
||||
return jsonObject;
|
||||
return inspector->getAssociatedExceptionDataForProtocol(exception);
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::Runtime::RemoteObject>
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "src/inspector/v8-profiler-agent-impl.h"
|
||||
#include "src/inspector/v8-runtime-agent-impl.h"
|
||||
#include "src/inspector/v8-stack-trace-impl.h"
|
||||
#include "src/inspector/value-mirror.h"
|
||||
|
||||
namespace v8_inspector {
|
||||
|
||||
@ -518,4 +519,24 @@ v8::MaybeLocal<v8::Object> V8InspectorImpl::getAssociatedExceptionData(
|
||||
return v8::MaybeLocal<v8::Object>();
|
||||
return scope.Escape(object.As<v8::Object>());
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::DictionaryValue>
|
||||
V8InspectorImpl::getAssociatedExceptionDataForProtocol(
|
||||
v8::Local<v8::Value> exception) {
|
||||
v8::MaybeLocal<v8::Object> maybeData = getAssociatedExceptionData(exception);
|
||||
v8::Local<v8::Object> data;
|
||||
if (!maybeData.ToLocal(&data)) return nullptr;
|
||||
|
||||
v8::Local<v8::Context> context;
|
||||
if (!exceptionMetaDataContext().ToLocal(&context)) return nullptr;
|
||||
|
||||
v8::TryCatch tryCatch(m_isolate);
|
||||
v8::MicrotasksScope microtasksScope(m_isolate,
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
v8::Context::Scope contextScope(context);
|
||||
std::unique_ptr<protocol::DictionaryValue> jsonObject;
|
||||
objectToProtocolValue(context, data, 2, &jsonObject);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
} // namespace v8_inspector
|
||||
|
@ -134,6 +134,8 @@ class V8InspectorImpl : public V8Inspector {
|
||||
int64_t generateUniqueId();
|
||||
V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Object> getAssociatedExceptionData(
|
||||
v8::Local<v8::Value> exception);
|
||||
std::unique_ptr<protocol::DictionaryValue>
|
||||
getAssociatedExceptionDataForProtocol(v8::Local<v8::Value> exception);
|
||||
|
||||
class EvaluateScope {
|
||||
public:
|
||||
|
@ -834,6 +834,13 @@ Response V8RuntimeAgentImpl::getExceptionDetails(
|
||||
// Lets use the normal message text instead.
|
||||
out_exceptionDetails->fromJust()->setText(
|
||||
toProtocolString(m_inspector->isolate(), message->Get()));
|
||||
|
||||
// Check if the exception has any metadata on the inspector and also attach
|
||||
// it.
|
||||
std::unique_ptr<protocol::DictionaryValue> data =
|
||||
m_inspector->getAssociatedExceptionDataForProtocol(error);
|
||||
if (data)
|
||||
out_exceptionDetails->fromJust()->setExceptionMetaData(std::move(data));
|
||||
return Response::Success();
|
||||
}
|
||||
|
||||
|
@ -68,3 +68,45 @@ Running test: itShouldReportAnErrorForNonJSErrorObjects
|
||||
}
|
||||
id : <messageId>
|
||||
}
|
||||
|
||||
Running test: itShouldIncludeMetaData
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
exceptionDetails : {
|
||||
columnNumber : 9
|
||||
exception : {
|
||||
className : Error
|
||||
description : Error: myerror at foo (<anonymous>:3:10) at <anonymous>:5:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
exceptionMetaData : {
|
||||
foo : bar
|
||||
}
|
||||
lineNumber : 2
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 9
|
||||
functionName : foo
|
||||
lineNumber : 2
|
||||
scriptId : <scriptId>
|
||||
url :
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 4
|
||||
scriptId : <scriptId>
|
||||
url :
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Error: myerror
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ function foo() {
|
||||
foo();
|
||||
`;
|
||||
|
||||
const expressionWithMeta = `
|
||||
function foo() {
|
||||
return new inspector.newExceptionWithMetaData('myerror', 'foo', 'bar');
|
||||
}
|
||||
foo();
|
||||
`;
|
||||
|
||||
InspectorTest.runAsyncTestSuite([
|
||||
async function itShouldReturnExceptionDetailsForJSErrorObjects() {
|
||||
await Protocol.Runtime.enable(); // Enable detailed stacktrace capturing.
|
||||
@ -31,5 +38,12 @@ InspectorTest.runAsyncTestSuite([
|
||||
const {result} = await Protocol.Runtime.evaluate({expression: '() =>({})'});
|
||||
InspectorTest.logMessage(await Protocol.Runtime.getExceptionDetails(
|
||||
{errorObjectId: result.result.objectId}));
|
||||
},
|
||||
|
||||
async function itShouldIncludeMetaData() {
|
||||
await Protocol.Runtime.enable(); // Enable detailed stacktrace capturing.
|
||||
const {result} = await Protocol.Runtime.evaluate({expression: expressionWithMeta});
|
||||
InspectorTest.logMessage(await Protocol.Runtime.getExceptionDetails(
|
||||
{errorObjectId: result.result.objectId}));
|
||||
}
|
||||
]);
|
||||
|
Loading…
Reference in New Issue
Block a user