Index: Source/modules/indexeddb/IDBRequest.cpp |
diff --git a/Source/modules/indexeddb/IDBRequest.cpp b/Source/modules/indexeddb/IDBRequest.cpp |
index c0109980da091fbdee3d8104660f31fdec62ad40..9d0d4c2efa48fd948f48a0caebffd02abeb6787a 100644 |
--- a/Source/modules/indexeddb/IDBRequest.cpp |
+++ b/Source/modules/indexeddb/IDBRequest.cpp |
@@ -31,10 +31,14 @@ |
#include "bindings/core/v8/ExceptionState.h" |
#include "bindings/core/v8/ExceptionStatePlaceholder.h" |
+#include "bindings/core/v8/ScriptCallStackFactory.h" |
#include "bindings/modules/v8/ToV8ForModules.h" |
#include "bindings/modules/v8/V8BindingForModules.h" |
#include "core/dom/ExecutionContext.h" |
+#include "core/events/ErrorEvent.h" |
#include "core/events/EventQueue.h" |
+#include "core/inspector/ScriptCallFrame.h" |
+#include "core/inspector/ScriptCallStack.h" |
#include "modules/IndexedDBNames.h" |
#include "modules/indexeddb/IDBCursorWithValue.h" |
#include "modules/indexeddb/IDBDatabase.h" |
@@ -64,6 +68,8 @@ IDBRequest::IDBRequest(ScriptState* scriptState, IDBAny* source, IDBTransaction* |
, m_scriptState(scriptState) |
, m_source(source) |
{ |
+ m_creationStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture); |
+ ASSERT(m_creationStack && m_creationStack->size()); |
} |
IDBRequest::~IDBRequest() |
@@ -81,6 +87,7 @@ DEFINE_TRACE(IDBRequest) |
visitor->trace(m_pendingCursor); |
visitor->trace(m_cursorKey); |
visitor->trace(m_cursorPrimaryKey); |
+ visitor->trace(m_creationStack); |
RefCountedGarbageCollectedEventTargetWithInlineData<IDBRequest>::trace(visitor); |
ActiveDOMObject::trace(visitor); |
} |
@@ -456,7 +463,7 @@ bool IDBRequest::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) |
if (setTransactionActive) |
m_transaction->setActive(true); |
- bool dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets); |
+ bool shouldPerformDefault = IDBEventDispatcher::dispatch(event.get(), targets); |
if (m_transaction) { |
if (m_readyState == DONE) |
@@ -464,7 +471,7 @@ bool IDBRequest::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) |
// Possibly abort the transaction. This must occur after unregistering (so this request |
// doesn't receive a second error) and before deactivating (which might trigger commit). |
- if (event->type() == EventTypeNames::error && dontPreventDefault && !m_requestAborted) { |
+ if (event->type() == EventTypeNames::error && shouldPerformDefault && !m_requestAborted) { |
m_transaction->setError(m_error); |
m_transaction->abort(IGNORE_EXCEPTION); |
} |
@@ -482,7 +489,19 @@ bool IDBRequest::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) |
if (m_readyState == DONE && event->type() != EventTypeNames::upgradeneeded) |
m_hasPendingActivity = false; |
- return dontPreventDefault; |
+ // Fire window.onerror (or the equivalent for workers) for errors that were not prevented. |
+ if (!m_preventPropagation && shouldPerformDefault && event->type() == EventTypeNames::error && m_creationStack.get() && m_creationStack->size()) { |
+ const ScriptCallFrame& frame = m_creationStack->at(0); |
+ const AccessControlStatus corsStatus = NotSharableCrossOrigin; |
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent; |
+ if (executionContext()->shouldSanitizeScriptError(frame.sourceURL(), corsStatus)) |
+ errorEvent = ErrorEvent::createSanitizedError(&m_scriptState->world()); |
+ else |
+ errorEvent = ErrorEvent::create(m_error->toStringForConsole(), frame.sourceURL(), frame.lineNumber(), frame.columnNumber(), &m_scriptState->world()); |
+ executionContext()->reportException(errorEvent, frame.scriptId().toInt(), m_creationStack, corsStatus); |
+ } |
+ |
+ return shouldPerformDefault; |
} |
void IDBRequest::uncaughtExceptionInEventHandler() |