Chromium Code Reviews| Index: Source/bindings/core/v8/V8Initializer.cpp |
| diff --git a/Source/bindings/core/v8/V8Initializer.cpp b/Source/bindings/core/v8/V8Initializer.cpp |
| index f73978540a245000a78a8a178ab3b90a6fb93a5a..ab1cc6afaa958b1db5ecc97a1eb1e432f3794c30 100644 |
| --- a/Source/bindings/core/v8/V8Initializer.cpp |
| +++ b/Source/bindings/core/v8/V8Initializer.cpp |
| @@ -30,6 +30,7 @@ |
| #include "bindings/core/v8/ScriptCallStackFactory.h" |
| #include "bindings/core/v8/ScriptController.h" |
| #include "bindings/core/v8/ScriptProfiler.h" |
| +#include "bindings/core/v8/ScriptValue.h" |
| #include "bindings/core/v8/V8Binding.h" |
| #include "bindings/core/v8/V8DOMException.h" |
| #include "bindings/core/v8/V8ErrorEvent.h" |
| @@ -45,6 +46,8 @@ |
| #include "core/frame/LocalDOMWindow.h" |
| #include "core/frame/LocalFrame.h" |
| #include "core/frame/csp/ContentSecurityPolicy.h" |
| +#include "core/inspector/ConsoleMessage.h" |
| +#include "core/inspector/ScriptArguments.h" |
| #include "core/inspector/ScriptCallStack.h" |
| #include "platform/EventDispatchForbiddenScope.h" |
| #include "platform/TraceEvent.h" |
| @@ -155,6 +158,61 @@ static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Hand |
| } |
| } |
| +typedef WillBeHeapDeque<ScriptValue> PromiseRejectMessageQueue; |
| + |
| +static PromiseRejectMessageQueue& promiseRejectMessageQueue() |
| +{ |
| + DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<PromiseRejectMessageQueue>, queue, (adoptPtrWillBeNoop(new PromiseRejectMessageQueue()))); |
| + return *queue; |
| +} |
| + |
| +void V8Initializer::reportRejectedPromises() |
| +{ |
| + ASSERT(isMainThread()); |
| + |
| + PromiseRejectMessageQueue& queue = promiseRejectMessageQueue(); |
| + while (!queue.isEmpty()) { |
| + ScriptValue promise = queue.takeFirst(); |
| + ScriptState* scriptState = promise.scriptState(); |
| + if (scriptState->contextIsValid()) |
|
pfeldman
2014/10/06 19:40:13
That's a really bad name. Lets swap the semantics
Jens Widell
2014/10/07 05:22:23
https://codereview.chromium.org/622333002/
aandrey
2014/10/07 10:03:37
Acknowledged.
|
| + continue; |
| + ScriptState::Scope scope(scriptState); |
| + |
| + ASSERT(!promise.isEmpty()); |
| + v8::Handle<v8::Value> value = promise.v8Value(); |
| + ASSERT(!value.IsEmpty() && value->IsPromise()); |
| + if (v8::Handle<v8::Promise>::Cast(value)->HasHandler()) |
| + continue; |
| + |
| + const String errorMessage = "Unhandled promise rejection"; |
| + Vector<ScriptValue> args; |
| + args.append(ScriptValue(scriptState, v8String(scriptState->isolate(), errorMessage))); |
| + args.append(promise); |
| + RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(scriptState, args); |
| + |
| + RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, "", 0); |
| + consoleMessage->setScriptArguments(arguments); |
| + scriptState->executionContext()->addConsoleMessage(consoleMessage.release()); |
|
yurys
2014/10/07 05:32:44
We should be careful not to call this on ScriptSta
aandrey
2014/10/07 10:03:37
Added a test, this case does not repro.
Seems like
|
| + } |
| +} |
| + |
| +static void promiseRejectHandlerInMainThread(v8::Handle<v8::Promise> promise, v8::Handle<v8::Value> /*value*/, v8::PromiseRejectEvent event) |
| +{ |
| + ASSERT(isMainThread()); |
| + |
| + if (event != v8::kPromiseRejectWithNoHandler) |
| + return; |
| + |
| + // It's possible that promiseRejectHandlerInMainThread() is invoked while we're initializing a window. |
| + // In that half-baked situation, we don't have a valid context nor a valid world, |
| + // so just return immediately. |
| + if (DOMWrapperWorld::windowIsBeingInitialized()) |
| + return; |
| + |
| + ScriptState* scriptState = ScriptState::current(promise->GetIsolate()); |
| + promiseRejectMessageQueue().append(ScriptValue(scriptState, promise)); |
| +} |
| + |
| static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) |
| { |
| v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| @@ -218,6 +276,7 @@ void V8Initializer::initializeMainThreadIfNeeded() |
| v8::V8::SetAllowCodeGenerationFromStringsCallback(codeGenerationCheckCallbackInMainThread); |
| isolate->SetEventLogger(timerTraceProfilerInMainThread); |
| + isolate->SetPromiseRejectCallback(promiseRejectHandlerInMainThread); |
| ScriptProfiler::initialize(); |
| } |