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

Unified Diff: Source/bindings/core/v8/V8Initializer.cpp

Issue 693183002: Show correct location of unhandled promise rejection messages when DevTools closed. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: Source/bindings/core/v8/V8Initializer.cpp
diff --git a/Source/bindings/core/v8/V8Initializer.cpp b/Source/bindings/core/v8/V8Initializer.cpp
index c015f4369ba6bc07caa1c6e6c5cabf3bde7b8558..eedbde6f1e810b2f74fcced568643b7485739254 100644
--- a/Source/bindings/core/v8/V8Initializer.cpp
+++ b/Source/bindings/core/v8/V8Initializer.cpp
@@ -166,8 +166,12 @@ namespace {
class PromiseRejectMessage {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
- PromiseRejectMessage(const ScriptValue& promise, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
+ PromiseRejectMessage(const ScriptValue& promise, const String& resourceURL, int scriptId, unsigned lineNumber, unsigned columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
: m_promise(promise)
+ , m_resourceURL(resourceURL)
+ , m_scriptId(scriptId)
+ , m_lineNumber(lineNumber)
+ , m_columnNumber(columnNumber)
, m_callStack(callStack)
{
}
@@ -178,6 +182,10 @@ public:
}
const ScriptValue m_promise;
+ const String m_resourceURL;
+ const int m_scriptId;
+ const unsigned m_lineNumber;
+ const unsigned m_columnNumber;
const RefPtrWillBeMember<ScriptCallStack> m_callStack;
};
@@ -220,18 +228,19 @@ void V8Initializer::reportRejectedPromises()
args.append(message.m_promise);
RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(scriptState, args);
- RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage);
+ RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, message.m_resourceURL, message.m_lineNumber, message.m_columnNumber);
consoleMessage->setScriptArguments(arguments);
consoleMessage->setCallStack(message.m_callStack);
+ consoleMessage->setScriptId(message.m_scriptId);
executionContext->addConsoleMessage(consoleMessage.release());
}
}
-static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message)
+static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
{
ASSERT(isMainThread());
- if (message.GetEvent() != v8::kPromiseRejectWithNoHandler)
+ if (data.GetEvent() != v8::kPromiseRejectWithNoHandler)
return;
// It's possible that promiseRejectHandlerInMainThread() is invoked while we're initializing a window.
@@ -240,7 +249,7 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message)
if (DOMWrapperWorld::windowIsBeingInitialized())
return;
- v8::Handle<v8::Promise> promise = message.GetPromise();
+ v8::Handle<v8::Promise> promise = data.GetPromise();
// Bail out if called during context initialization.
v8::Isolate* isolate = promise->GetIsolate();
@@ -250,35 +259,59 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message)
v8::Handle<v8::Value> global = V8Window::findInstanceInPrototypeChain(context->Global(), context->GetIsolate());
if (global.IsEmpty())
return;
- if (!toFrameIfNotDetached(context))
+
+ // There is no entered window during microtask callbacks from V8,
+ // thus we call toDOMWindow() instead of enteredDOMWindow().
+ LocalDOMWindow* window = toDOMWindow(context);
+ if (!window || !window->isCurrentlyDisplayedInFrame())
return;
+ v8::Handle<v8::Value> exception = data.GetValue();
+ if (V8DOMWrapper::isDOMWrapper(exception)) {
+ // Try to get the stack & location from a wrapped exception object (e.g. DOMException).
+ ASSERT(exception->IsObject());
+ v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(exception);
+ v8::Handle<v8::Value> error = V8HiddenValue::getHiddenValue(isolate, obj, V8HiddenValue::error(isolate));
+ if (!error.IsEmpty())
+ exception = error;
+ }
+
+ int scriptId = 0;
+ unsigned lineNumber = 0;
+ unsigned columnNumber = 0;
+ String resourceURL;
RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr;
- v8::Handle<v8::StackTrace> stackTrace = message.GetStackTrace();
- if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
- callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate);
- if (!callStack && V8DOMWrapper::isDOMWrapper(message.GetValue())) {
- // Try to get the stack from a wrapped exception object (e.g. DOMException).
- v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(message.GetValue());
- v8::Handle<v8::Value> error = V8HiddenValue::getHiddenValue(isolate, obj, V8HiddenValue::error(isolate));
- if (!error.IsEmpty()) {
- stackTrace = v8::Exception::GetStackTrace(error);
- if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
- callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate);
+ v8::Handle<v8::Message> message = v8::Exception::GetMessage(exception);
+ if (!message.IsEmpty()) {
+ scriptId = message->GetScriptOrigin().ScriptID()->Value();
+ lineNumber = static_cast<unsigned>(message->GetLineNumber());
+ columnNumber = static_cast<unsigned>(message->GetStartColumn() + 1);
+
+ v8::Handle<v8::Value> resourceName = message->GetScriptOrigin().ResourceName();
vsevik 2014/11/07 06:26:38 Looks like a lot of copy-paste here. Can we at lea
aandrey 2014/11/10 11:44:33 Done.
+ bool shouldUseDocumentURL = window->document() && (resourceName.IsEmpty() || !resourceName->IsString());
+ resourceURL = shouldUseDocumentURL ? window->document()->url() : toCoreString(resourceName.As<v8::String>());
+
+ v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace();
vsevik 2014/11/07 06:26:39 extract callStack(stackTrace, isolate)?
aandrey 2014/11/10 11:44:33 Done.
+ if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) {
+ callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate);
+ bool success = false;
+ int topScriptId = callStack->at(0).scriptId().toInt(&success);
+ if (success && topScriptId == scriptId)
+ scriptId = 0;
vsevik 2014/11/07 06:26:38 extract scriptId(callStack, scriptOrigin)?
aandrey 2014/11/10 11:44:33 Acknowledged.
}
}
ScriptState* scriptState = ScriptState::from(context);
- promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), callStack));
+ promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), resourceURL, scriptId, lineNumber, columnNumber, callStack));
}
-static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage message)
+static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
{
- if (message.GetEvent() != v8::kPromiseRejectWithNoHandler)
+ if (data.GetEvent() != v8::kPromiseRejectWithNoHandler)
return;
- v8::Handle<v8::Promise> promise = message.GetPromise();
+ v8::Handle<v8::Promise> promise = data.GetPromise();
// Bail out if called during context initialization.
v8::Isolate* isolate = promise->GetIsolate();
@@ -286,13 +319,21 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage message)
if (context.IsEmpty())
return;
- RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr;
- v8::Handle<v8::StackTrace> stackTrace = message.GetStackTrace();
- if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
- callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate);
+ int scriptId = 0;
+ unsigned lineNumber = 0;
+ unsigned columnNumber = 0;
+ String resourceURL;
+
+ v8::Handle<v8::Message> message = v8::Exception::GetMessage(data.GetValue());
+ if (!message.IsEmpty()) {
+ TOSTRING_VOID(V8StringResource<>, resourceURL, message->GetScriptOrigin().ResourceName());
+ scriptId = message->GetScriptOrigin().ScriptID()->Value();
vsevik 2014/11/07 06:26:38 This is not correct way to use scriptId parameter
yurys 2014/11/07 12:49:27 Can you file a bug on this?
+ lineNumber = static_cast<unsigned>(message->GetLineNumber());
+ columnNumber = static_cast<unsigned>(message->GetStartColumn() + 1);
+ }
ScriptState* scriptState = ScriptState::from(context);
- promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), callStack));
+ promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), resourceURL, scriptId, lineNumber, columnNumber, nullptr));
}
static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)

Powered by Google App Engine
This is Rietveld 408576698