| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bindings/core/v8/RejectedPromises.h" | 5 #include "bindings/core/v8/RejectedPromises.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScopedPersistent.h" | 7 #include "bindings/core/v8/ScopedPersistent.h" |
| 8 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
| 9 #include "bindings/core/v8/ScriptValue.h" | 9 #include "bindings/core/v8/ScriptValue.h" |
| 10 #include "bindings/core/v8/V8Binding.h" | 10 #include "bindings/core/v8/V8Binding.h" |
| 11 #include "bindings/core/v8/V8PerIsolateData.h" |
| 11 #include "core/dom/ExecutionContext.h" | 12 #include "core/dom/ExecutionContext.h" |
| 12 #include "core/events/EventTarget.h" | 13 #include "core/events/EventTarget.h" |
| 13 #include "core/events/PromiseRejectionEvent.h" | 14 #include "core/events/PromiseRejectionEvent.h" |
| 14 #include "core/inspector/ConsoleMessage.h" | 15 #include "core/inspector/ThreadDebugger.h" |
| 15 #include "core/inspector/ScriptArguments.h" | |
| 16 #include "platform/RuntimeEnabledFeatures.h" | 16 #include "platform/RuntimeEnabledFeatures.h" |
| 17 #include "public/platform/Platform.h" | 17 #include "public/platform/Platform.h" |
| 18 #include "public/platform/WebScheduler.h" | 18 #include "public/platform/WebScheduler.h" |
| 19 #include "public/platform/WebTaskRunner.h" | 19 #include "public/platform/WebTaskRunner.h" |
| 20 #include "public/platform/WebThread.h" | 20 #include "public/platform/WebThread.h" |
| 21 #include "wtf/Functional.h" | 21 #include "wtf/Functional.h" |
| 22 | 22 |
| 23 namespace blink { | 23 namespace blink { |
| 24 | 24 |
| 25 static const unsigned maxReportedHandlersPendingResolution = 1000; | 25 static const unsigned maxReportedHandlersPendingResolution = 1000; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 PromiseRejectionEventInit init; | 66 PromiseRejectionEventInit init; |
| 67 init.setPromise(ScriptPromise(m_scriptState, value)); | 67 init.setPromise(ScriptPromise(m_scriptState, value)); |
| 68 init.setReason(ScriptValue(m_scriptState, reason)); | 68 init.setReason(ScriptValue(m_scriptState, reason)); |
| 69 init.setCancelable(true); | 69 init.setCancelable(true); |
| 70 PromiseRejectionEvent* event = PromiseRejectionEvent::create(m_scrip
tState, EventTypeNames::unhandledrejection, init); | 70 PromiseRejectionEvent* event = PromiseRejectionEvent::create(m_scrip
tState, EventTypeNames::unhandledrejection, init); |
| 71 // Log to console if event was not canceled. | 71 // Log to console if event was not canceled. |
| 72 m_shouldLogToConsole = target->dispatchEvent(event) == DispatchEvent
Result::NotCanceled; | 72 m_shouldLogToConsole = target->dispatchEvent(event) == DispatchEvent
Result::NotCanceled; |
| 73 } | 73 } |
| 74 | 74 |
| 75 if (m_shouldLogToConsole) { | 75 if (m_shouldLogToConsole) { |
| 76 const String errorMessage = "Uncaught (in promise)"; | 76 V8PerIsolateData* data = V8PerIsolateData::from(m_scriptState->isola
te()); |
| 77 Vector<ScriptValue> args; | 77 if (data->threadDebugger()) |
| 78 args.append(ScriptValue(m_scriptState, v8String(m_scriptState->isola
te(), errorMessage))); | 78 m_promiseRejectionId = data->threadDebugger()->debugger()->promi
seRejected(m_scriptState->context(), m_errorMessage, reason, m_location->url(),
m_location->lineNumber(), m_location->columnNumber(), m_location->cloneStackTrac
e(), m_location->scriptId()); |
| 79 args.append(ScriptValue(m_scriptState, reason)); | |
| 80 ScriptArguments* arguments = ScriptArguments::create(m_scriptState,
args); | |
| 81 | |
| 82 String embedderErrorMessage = m_errorMessage; | |
| 83 if (embedderErrorMessage.isEmpty()) | |
| 84 embedderErrorMessage = errorMessage; | |
| 85 else if (embedderErrorMessage.startsWith("Uncaught ")) | |
| 86 embedderErrorMessage.insert(" (in promise)", 8); | |
| 87 | |
| 88 ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSou
rce, ErrorMessageLevel, embedderErrorMessage, std::move(m_location), arguments); | |
| 89 m_consoleMessageId = consoleMessage->assignMessageId(); | |
| 90 executionContext->addConsoleMessage(consoleMessage); | |
| 91 } | 79 } |
| 92 | 80 |
| 93 m_location.reset(); | 81 m_location.reset(); |
| 94 } | 82 } |
| 95 | 83 |
| 96 void revoke() | 84 void revoke() |
| 97 { | 85 { |
| 98 ExecutionContext* executionContext = m_scriptState->getExecutionContext(
); | 86 ExecutionContext* executionContext = m_scriptState->getExecutionContext(
); |
| 99 if (!executionContext) | 87 if (!executionContext) |
| 100 return; | 88 return; |
| 101 | 89 |
| 102 ScriptState::Scope scope(m_scriptState); | 90 ScriptState::Scope scope(m_scriptState); |
| 103 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); | 91 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); |
| 104 v8::Local<v8::Value> reason = m_exception.newLocal(m_scriptState->isolat
e()); | 92 v8::Local<v8::Value> reason = m_exception.newLocal(m_scriptState->isolat
e()); |
| 105 // Either collected or https://crbug.com/450330 | 93 // Either collected or https://crbug.com/450330 |
| 106 if (value.IsEmpty() || !value->IsPromise()) | 94 if (value.IsEmpty() || !value->IsPromise()) |
| 107 return; | 95 return; |
| 108 | 96 |
| 109 EventTarget* target = executionContext->errorEventTarget(); | 97 EventTarget* target = executionContext->errorEventTarget(); |
| 110 if (RuntimeEnabledFeatures::promiseRejectionEventEnabled() && target &&
!executionContext->shouldSanitizeScriptError(m_resourceName, m_corsStatus)) { | 98 if (RuntimeEnabledFeatures::promiseRejectionEventEnabled() && target &&
!executionContext->shouldSanitizeScriptError(m_resourceName, m_corsStatus)) { |
| 111 PromiseRejectionEventInit init; | 99 PromiseRejectionEventInit init; |
| 112 init.setPromise(ScriptPromise(m_scriptState, value)); | 100 init.setPromise(ScriptPromise(m_scriptState, value)); |
| 113 init.setReason(ScriptValue(m_scriptState, reason)); | 101 init.setReason(ScriptValue(m_scriptState, reason)); |
| 114 PromiseRejectionEvent* event = PromiseRejectionEvent::create(m_scrip
tState, EventTypeNames::rejectionhandled, init); | 102 PromiseRejectionEvent* event = PromiseRejectionEvent::create(m_scrip
tState, EventTypeNames::rejectionhandled, init); |
| 115 target->dispatchEvent(event); | 103 target->dispatchEvent(event); |
| 116 } | 104 } |
| 117 | 105 |
| 118 if (m_shouldLogToConsole) { | 106 if (m_shouldLogToConsole && m_promiseRejectionId) { |
| 119 ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSou
rce, RevokedErrorMessageLevel, "Handler added to rejected promise"); | 107 V8PerIsolateData* data = V8PerIsolateData::from(m_scriptState->isola
te()); |
| 120 consoleMessage->setRelatedMessageId(m_consoleMessageId); | 108 if (data->threadDebugger()) |
| 121 executionContext->addConsoleMessage(consoleMessage); | 109 data->threadDebugger()->debugger()->promiseRejectionRevoked(m_sc
riptState->context(), m_promiseRejectionId); |
| 122 } | 110 } |
| 123 } | 111 } |
| 124 | 112 |
| 125 void makePromiseWeak() | 113 void makePromiseWeak() |
| 126 { | 114 { |
| 127 ASSERT(!m_promise.isEmpty() && !m_promise.isWeak()); | 115 ASSERT(!m_promise.isEmpty() && !m_promise.isWeak()); |
| 128 m_promise.setWeak(this, &Message::didCollectPromise); | 116 m_promise.setWeak(this, &Message::didCollectPromise); |
| 129 m_exception.setWeak(this, &Message::didCollectException); | 117 m_exception.setWeak(this, &Message::didCollectException); |
| 130 } | 118 } |
| 131 | 119 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 145 } | 133 } |
| 146 | 134 |
| 147 private: | 135 private: |
| 148 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) | 136 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) |
| 149 : m_scriptState(scriptState) | 137 : m_scriptState(scriptState) |
| 150 , m_promise(scriptState->isolate(), promise) | 138 , m_promise(scriptState->isolate(), promise) |
| 151 , m_exception(scriptState->isolate(), exception) | 139 , m_exception(scriptState->isolate(), exception) |
| 152 , m_errorMessage(errorMessage) | 140 , m_errorMessage(errorMessage) |
| 153 , m_resourceName(location->url()) | 141 , m_resourceName(location->url()) |
| 154 , m_location(std::move(location)) | 142 , m_location(std::move(location)) |
| 155 , m_consoleMessageId(0) | 143 , m_promiseRejectionId(0) |
| 156 , m_collected(false) | 144 , m_collected(false) |
| 157 , m_shouldLogToConsole(true) | 145 , m_shouldLogToConsole(true) |
| 158 , m_corsStatus(corsStatus) | 146 , m_corsStatus(corsStatus) |
| 159 { | 147 { |
| 160 } | 148 } |
| 161 | 149 |
| 162 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) | 150 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) |
| 163 { | 151 { |
| 164 data.GetParameter()->m_collected = true; | 152 data.GetParameter()->m_collected = true; |
| 165 data.GetParameter()->m_promise.clear(); | 153 data.GetParameter()->m_promise.clear(); |
| 166 } | 154 } |
| 167 | 155 |
| 168 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) | 156 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) |
| 169 { | 157 { |
| 170 data.GetParameter()->m_exception.clear(); | 158 data.GetParameter()->m_exception.clear(); |
| 171 } | 159 } |
| 172 | 160 |
| 173 ScriptState* m_scriptState; | 161 ScriptState* m_scriptState; |
| 174 ScopedPersistent<v8::Promise> m_promise; | 162 ScopedPersistent<v8::Promise> m_promise; |
| 175 ScopedPersistent<v8::Value> m_exception; | 163 ScopedPersistent<v8::Value> m_exception; |
| 176 String m_errorMessage; | 164 String m_errorMessage; |
| 177 String m_resourceName; | 165 String m_resourceName; |
| 178 OwnPtr<SourceLocation> m_location; | 166 OwnPtr<SourceLocation> m_location; |
| 179 unsigned m_consoleMessageId; | 167 unsigned m_promiseRejectionId; |
| 180 bool m_collected; | 168 bool m_collected; |
| 181 bool m_shouldLogToConsole; | 169 bool m_shouldLogToConsole; |
| 182 AccessControlStatus m_corsStatus; | 170 AccessControlStatus m_corsStatus; |
| 183 }; | 171 }; |
| 184 | 172 |
| 185 RejectedPromises::RejectedPromises() | 173 RejectedPromises::RejectedPromises() |
| 186 { | 174 { |
| 187 } | 175 } |
| 188 | 176 |
| 189 RejectedPromises::~RejectedPromises() | 177 RejectedPromises::~RejectedPromises() |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 253 } |
| 266 } | 254 } |
| 267 } | 255 } |
| 268 | 256 |
| 269 void RejectedPromises::revokeNow(PassOwnPtr<Message> message) | 257 void RejectedPromises::revokeNow(PassOwnPtr<Message> message) |
| 270 { | 258 { |
| 271 message->revoke(); | 259 message->revoke(); |
| 272 } | 260 } |
| 273 | 261 |
| 274 } // namespace blink | 262 } // namespace blink |
| OLD | NEW |