IndexedDB: Implement spec updates to IDBTransaction.error
authorjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2012 00:31:41 +0000 (00:31 +0000)
committerjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2012 00:31:41 +0000 (00:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91409

Reviewed by Tony Chang.

Source/WebCore:

The Indexed DB spec was updated to resolve some edge cases around the
IDBTransaction.error attribute. It was agreed that accessing error should
never throw, error should be null if the transaction is not finished or
abort() was explicitly called, an appropriate error should be returned if
a commit failed, and a generic AbortError should be used if a request
callback throws. These cases are now handled per spec, except that a reason
is not provided for the commit failure (it's always UnknownError).

Test: storage/indexeddb/transaction-error.html
      storage/indexeddb/transaction-abort.html

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::dispatchEvent): Refactor some nested if() blocks; don't
re-abort the transaction if dispatching in response to an abort.
(WebCore::IDBRequest::uncaughtExceptionInEventHandler): Abort transaction
only if not already aborting, and set it's error to AbortError.
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::onAbort): Set error if abort triggered by back end.
* Modules/indexeddb/IDBTransaction.h:
(WebCore::IDBTransaction::db): Move impl to header file.
(WebCore::IDBTransaction::error): Move impl to header file, simplify.
(IDBTransaction):
* Modules/indexeddb/IDBTransaction.idl: The error attribute no longer throws.

LayoutTests:

Update transaction-abort test to accomodate refinements in the spec around
IDBTransaction.error and add a dedicated test to exercise all spec behavior
for the property.

* storage/indexeddb/resources/transaction-abort.js:
(startTest):
(firstAdd):
(secondAdd):
(transactionAborted):
* storage/indexeddb/resources/transaction-error.js: Added.
(test.request.onsuccess.request.onsuccess.request.onsuccess):
(test.request.onsuccess.request.onsuccess):
(test.request.onsuccess):
(test):
(startTest.trans.onabort):
(startTest):
(testErrorFromRequest.request.onerror):
(testErrorFromRequest.trans.onabort):
(testErrorFromRequest):
(testErrorFromException.request.onerror):
(testErrorFromException.trans.onabort):
(testErrorFromException):
* storage/indexeddb/transaction-abort-expected.txt:
* storage/indexeddb/transaction-error-expected.txt: Added.
* storage/indexeddb/transaction-error.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@122782 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/resources/transaction-abort.js
LayoutTests/storage/indexeddb/resources/transaction-error.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/transaction-abort-expected.txt
LayoutTests/storage/indexeddb/transaction-error-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/transaction-error.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
Source/WebCore/Modules/indexeddb/IDBTransaction.h
Source/WebCore/Modules/indexeddb/IDBTransaction.idl

index 5489eb2..fa62601 100644 (file)
@@ -1,3 +1,36 @@
+2012-07-16  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Implement spec updates to IDBTransaction.error
+        https://bugs.webkit.org/show_bug.cgi?id=91409
+
+        Reviewed by Tony Chang.
+
+        Update transaction-abort test to accomodate refinements in the spec around
+        IDBTransaction.error and add a dedicated test to exercise all spec behavior 
+        for the property.
+
+        * storage/indexeddb/resources/transaction-abort.js:
+        (startTest):
+        (firstAdd):
+        (secondAdd):
+        (transactionAborted):
+        * storage/indexeddb/resources/transaction-error.js: Added.
+        (test.request.onsuccess.request.onsuccess.request.onsuccess):
+        (test.request.onsuccess.request.onsuccess):
+        (test.request.onsuccess):
+        (test):
+        (startTest.trans.onabort):
+        (startTest):
+        (testErrorFromRequest.request.onerror):
+        (testErrorFromRequest.trans.onabort):
+        (testErrorFromRequest):
+        (testErrorFromException.request.onerror):
+        (testErrorFromException.trans.onabort):
+        (testErrorFromException):
+        * storage/indexeddb/transaction-abort-expected.txt:
+        * storage/indexeddb/transaction-error-expected.txt: Added.
+        * storage/indexeddb/transaction-error.html: Added.
+
 2012-07-16  W. James MacLean  <wjmaclean@chromium.org>
 
         [chromium] Unreviewed gardening. Layout Test plugins/embed-attributes-style.html is failing
 2012-07-16  W. James MacLean  <wjmaclean@chromium.org>
 
         [chromium] Unreviewed gardening. Layout Test plugins/embed-attributes-style.html is failing
index 833e6b8..6ade025 100644 (file)
@@ -49,6 +49,7 @@ function startTest()
     request.onsuccess = unexpectedSuccessCallback;
     request = evalAndLog("store.add({x: 'value3', y: 'zzz3'}, 'key3')");
     request.onerror = secondAdd;
     request.onsuccess = unexpectedSuccessCallback;
     request = evalAndLog("store.add({x: 'value3', y: 'zzz3'}, 'key3')");
     request.onerror = secondAdd;
+    request.onsuccess = unexpectedSuccessCallback;
     trans.abort();
 
     firstError = false;
     trans.abort();
 
     firstError = false;
@@ -60,10 +61,7 @@ function firstAdd()
 {
     shouldBe("event.target.errorCode", "DOMException.ABORT_ERR");
     shouldBe("event.target.error.name", "'AbortError'");
 {
     shouldBe("event.target.errorCode", "DOMException.ABORT_ERR");
     shouldBe("event.target.error.name", "'AbortError'");
-    firstDOMError = event.target.error;
-    // FIXME: Ambiguous spec. See: https://www.w3.org/Bugs/Public/show_bug.cgi?id=17236
-    evalAndExpectException("trans.error", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
-
+    shouldBeNull("trans.error");
     shouldBeFalse("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
     shouldBeFalse("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
@@ -76,8 +74,7 @@ function secondAdd()
 {
     shouldBe("event.target.errorCode", "DOMException.ABORT_ERR");
     shouldBe("event.target.error.name", "'AbortError'");
 {
     shouldBe("event.target.errorCode", "DOMException.ABORT_ERR");
     shouldBe("event.target.error.name", "'AbortError'");
-    // FIXME: Ambiguous spec. See: https://www.w3.org/Bugs/Public/show_bug.cgi?id=17236
-    evalAndExpectException("trans.error", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
+    shouldBeNull("trans.error");
     shouldBeTrue("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
     shouldBeTrue("firstError");
     shouldBeFalse("secondError");
     shouldBeFalse("abortFired");
@@ -89,11 +86,11 @@ function transactionAborted()
     shouldBeTrue("firstError");
     shouldBeTrue("secondError");
     shouldBeFalse("abortFired");
     shouldBeTrue("firstError");
     shouldBeTrue("secondError");
     shouldBeFalse("abortFired");
-    shouldBe("trans.error", "firstDOMError");
+    shouldBeNull("trans.error");
     abortFired = true;
 
     evalAndExpectException("store.add({x: 'value5', y: 'zzz5'}, 'key5')", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR", "'TransactionInactiveError'");
     finishJSTest();
 }
 
     abortFired = true;
 
     evalAndExpectException("store.add({x: 'value5', y: 'zzz5'}, 'key5')", "IDBDatabaseException.TRANSACTION_INACTIVE_ERR", "'TransactionInactiveError'");
     finishJSTest();
 }
 
-test();
\ No newline at end of file
+test();
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-error.js b/LayoutTests/storage/indexeddb/resources/transaction-error.js
new file mode 100644 (file)
index 0000000..581dc11
--- /dev/null
@@ -0,0 +1,138 @@
+if (this.importScripts) {
+    importScripts('../../../fast/js/resources/js-test-pre.js');
+    importScripts('shared.js');
+}
+
+description("Test IDBTransaction.error cases.");
+
+function test()
+{
+    removeVendorPrefixes();
+
+    evalAndLog("dbname = self.location.pathname");
+    request = evalAndLog("indexedDB.deleteDatabase(dbname)");
+    request.onblocked = unexpectedBlockedCallback;
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function() {
+        request = evalAndLog("indexedDB.open(dbname)");
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = function() {
+            evalAndLog("db = request.result");
+            request = evalAndLog("db.setVersion('1')");
+            request.onblocked = unexpectedBlockedCallback;
+            request.onerror = unexpectedErrorCallback;
+            request.onsuccess = function() {
+                evalAndLog("trans = event.target.result");
+                trans.onabort = unexpectedAbortCallback;
+                evalAndLog("store = db.createObjectStore('storeName')");
+                request = evalAndLog("store.add('value', 'key')");
+                request.onerror = unexpectedErrorCallback;
+                trans.oncomplete = startTest;
+            };
+        };
+    };
+}
+
+function startTest()
+{
+    debug("");
+    evalAndLog("trans = db.transaction('storeName')");
+
+    debug("");
+    debug("IDBTransaction.error should be null if transaction is not finished:");
+    shouldBeNull("trans.error");
+
+    debug("");
+    debug("If IDBTransaction.abort() is explicitly called, IDBTransaction.error should be null:");
+    evalAndLog("trans.abort()");
+    trans.oncomplete = unexpectedCompleteCallback;
+    trans.onabort = function() {
+        shouldBeNull("trans.error");
+        testErrorFromRequest();
+    };
+}
+
+function testErrorFromRequest()
+{
+    debug("");
+    debug("If the transaction is aborted due to a request error that is not prevented, IDBTransaction.error should match:");
+    evalAndLog("trans = db.transaction('storeName', 'readwrite')");
+    evalAndLog("request = trans.objectStore('storeName').add('value2', 'key')");
+    request.onsuccess = unexpectedSuccessCallback;
+    request.onerror = function() {
+        shouldBe("request.errorCode", "IDBDatabaseException.CONSTRAINT_ERR");
+        shouldBe("request.error.name", "'ConstraintError'");
+        evalAndLog("request_error = request.error");
+    };
+    trans.oncomplete = unexpectedCompleteCallback;
+    trans.onabort = function() {
+        debug("Transaction received abort event.");
+        shouldBeNonNull("trans.error");
+        shouldBe("trans.error", "request_error");
+        testErrorFromException();
+    };
+}
+
+function testErrorFromException()
+{
+    debug("");
+    debug("If the transaction is aborted due to an exception thrown from event callback, IDBTransaction.error should be AbortError:");
+    evalAndLog("trans = db.transaction('storeName', 'readwrite')");
+    evalAndLog("request = trans.objectStore('storeName').add('value2', 'key')");
+    request.onsuccess = unexpectedSuccessCallback;
+    request.onerror = function() {
+        shouldBe("request.errorCode", "IDBDatabaseException.CONSTRAINT_ERR");
+        shouldBe("request.error.name", "'ConstraintError'");
+        debug("Throwing exception...");
+
+        // Ensure the test harness error handler is not invoked.
+        self.originalWindowOnError = self.onerror;
+        self.onerror = null;
+
+        throw new Error("This should *NOT* be caught!");
+    };
+    trans.oncomplete = unexpectedCompleteCallback;
+    trans.onabort = function() {
+        debug("Transaction received abort event.");
+
+        // Restore test harness error handler.
+        self.onerror = self.originalWindowOnError;
+
+        shouldBeNonNull("trans.error");
+        shouldBe("trans.error.name", "'AbortError'");
+        testErrorFromCommit();
+    };
+}
+
+function testErrorFromCommit()
+{
+    debug("");
+    debug("If the transaction is aborted due to an error during commit, IDBTransaction.error should reflect that error:");
+    evalAndLog("trans = db.transaction('storeName', 'readwrite')");
+    evalAndLog("request = trans.objectStore('storeName').add({id: 1}, 'record1')");
+    request.onerror = unexpectedErrorCallback;
+    evalAndLog("request = trans.objectStore('storeName').add({id: 1}, 'record2')");
+    request.onerror = unexpectedErrorCallback;
+    trans.onabort = unexpectedAbortCallback;
+    trans.oncomplete = function() {
+        evalAndLog("request = db.setVersion('2')");
+        request.onerror = unexpectedErrorCallback;
+        request.onblocked = unexpectedBlockedCallback;
+        request.onsuccess = function() {
+            evalAndLog("trans = request.result");
+            debug("This should fail due to the unique constraint:");
+            evalAndLog("trans.objectStore('storeName').createIndex('indexName', 'id', {unique: true})");
+            trans.oncomplete = unexpectedCompleteCallback;
+            trans.onabort = function() {
+                debug("Transaction received abort event.");
+                shouldBeNonNull("trans.error");
+                // FIXME: Test for a specific error here, when supported.
+                shouldNotBe("trans.error.name", "'AbortError'");
+                debug("");
+                finishJSTest();
+            };
+        };
+    };
+}
+
+test();
index 92a1b36..e929cd7 100644 (file)
@@ -23,10 +23,7 @@ store.add({x: 'value2', y: 'zzz2'}, 'key2')
 store.add({x: 'value3', y: 'zzz3'}, 'key3')
 PASS event.target.errorCode is DOMException.ABORT_ERR
 PASS event.target.error.name is 'AbortError'
 store.add({x: 'value3', y: 'zzz3'}, 'key3')
 PASS event.target.errorCode is DOMException.ABORT_ERR
 PASS event.target.error.name is 'AbortError'
-Expecting exception from trans.error
-PASS Exception was thrown.
-PASS code is DOMException.INVALID_STATE_ERR
-PASS ename is 'InvalidStateError'
+PASS trans.error is null
 PASS firstError is false
 PASS secondError is false
 PASS abortFired is false
 PASS firstError is false
 PASS secondError is false
 PASS abortFired is false
@@ -36,17 +33,14 @@ PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
 PASS ename is 'TransactionInactiveError'
 PASS event.target.errorCode is DOMException.ABORT_ERR
 PASS event.target.error.name is 'AbortError'
 PASS ename is 'TransactionInactiveError'
 PASS event.target.errorCode is DOMException.ABORT_ERR
 PASS event.target.error.name is 'AbortError'
-Expecting exception from trans.error
-PASS Exception was thrown.
-PASS code is DOMException.INVALID_STATE_ERR
-PASS ename is 'InvalidStateError'
+PASS trans.error is null
 PASS firstError is true
 PASS secondError is false
 PASS abortFired is false
 PASS firstError is true
 PASS secondError is true
 PASS abortFired is false
 PASS firstError is true
 PASS secondError is false
 PASS abortFired is false
 PASS firstError is true
 PASS secondError is true
 PASS abortFired is false
-PASS trans.error is firstDOMError
+PASS trans.error is null
 Expecting exception from store.add({x: 'value5', y: 'zzz5'}, 'key5')
 PASS Exception was thrown.
 PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
 Expecting exception from store.add({x: 'value5', y: 'zzz5'}, 'key5')
 PASS Exception was thrown.
 PASS code is IDBDatabaseException.TRANSACTION_INACTIVE_ERR
diff --git a/LayoutTests/storage/indexeddb/transaction-error-expected.txt b/LayoutTests/storage/indexeddb/transaction-error-expected.txt
new file mode 100644 (file)
index 0000000..b4fba9a
--- /dev/null
@@ -0,0 +1,62 @@
+CONSOLE MESSAGE: line 92: Uncaught Error: This should *NOT* be caught!
+Test IDBTransaction.error cases.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = self.location.pathname
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+db = request.result
+db.setVersion('1')
+trans = event.target.result
+store = db.createObjectStore('storeName')
+store.add('value', 'key')
+
+trans = db.transaction('storeName')
+
+IDBTransaction.error should be null if transaction is not finished:
+PASS trans.error is null
+
+If IDBTransaction.abort() is explicitly called, IDBTransaction.error should be null:
+trans.abort()
+PASS trans.error is null
+
+If the transaction is aborted due to a request error that is not prevented, IDBTransaction.error should match:
+trans = db.transaction('storeName', 'readwrite')
+request = trans.objectStore('storeName').add('value2', 'key')
+PASS request.errorCode is IDBDatabaseException.CONSTRAINT_ERR
+PASS request.error.name is 'ConstraintError'
+request_error = request.error
+Transaction received abort event.
+PASS trans.error is non-null.
+PASS trans.error is request_error
+
+If the transaction is aborted due to an exception thrown from event callback, IDBTransaction.error should be AbortError:
+trans = db.transaction('storeName', 'readwrite')
+request = trans.objectStore('storeName').add('value2', 'key')
+PASS request.errorCode is IDBDatabaseException.CONSTRAINT_ERR
+PASS request.error.name is 'ConstraintError'
+Throwing exception...
+Transaction received abort event.
+PASS trans.error is non-null.
+PASS trans.error.name is 'AbortError'
+
+If the transaction is aborted due to an error during commit, IDBTransaction.error should reflect that error:
+trans = db.transaction('storeName', 'readwrite')
+request = trans.objectStore('storeName').add({id: 1}, 'record1')
+request = trans.objectStore('storeName').add({id: 1}, 'record2')
+request = db.setVersion('2')
+trans = request.result
+This should fail due to the unique constraint:
+trans.objectStore('storeName').createIndex('indexName', 'id', {unique: true})
+Transaction received abort event.
+PASS trans.error is non-null.
+PASS trans.error.name is not 'AbortError'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/transaction-error.html b/LayoutTests/storage/indexeddb/transaction-error.html
new file mode 100644 (file)
index 0000000..3c0c7ce
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<script src="resources/transaction-error.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 3082005..0d81011 100644 (file)
@@ -1,3 +1,34 @@
+2012-07-16  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Implement spec updates to IDBTransaction.error
+        https://bugs.webkit.org/show_bug.cgi?id=91409
+
+        Reviewed by Tony Chang.
+
+        The Indexed DB spec was updated to resolve some edge cases around the
+        IDBTransaction.error attribute. It was agreed that accessing error should
+        never throw, error should be null if the transaction is not finished or
+        abort() was explicitly called, an appropriate error should be returned if
+        a commit failed, and a generic AbortError should be used if a request
+        callback throws. These cases are now handled per spec, except that a reason
+        is not provided for the commit failure (it's always UnknownError).
+
+        Test: storage/indexeddb/transaction-error.html
+              storage/indexeddb/transaction-abort.html
+
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::dispatchEvent): Refactor some nested if() blocks; don't
+        re-abort the transaction if dispatching in response to an abort.
+        (WebCore::IDBRequest::uncaughtExceptionInEventHandler): Abort transaction
+        only if not already aborting, and set it's error to AbortError.
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::onAbort): Set error if abort triggered by back end.
+        * Modules/indexeddb/IDBTransaction.h:
+        (WebCore::IDBTransaction::db): Move impl to header file.
+        (WebCore::IDBTransaction::error): Move impl to header file, simplify.
+        (IDBTransaction):
+        * Modules/indexeddb/IDBTransaction.idl: The error attribute no longer throws.
+
 2012-07-16  Alec Flett  <alecflett@chromium.org>
 
         IndexedDB: Introduce putWithIndexKeys and calculate them in the renderer
 2012-07-16  Alec Flett  <alecflett@chromium.org>
 
         IndexedDB: Introduce putWithIndexKeys and calculate them in the renderer
index 63a48be..54afe03 100644 (file)
@@ -439,25 +439,28 @@ bool IDBRequest::dispatchEvent(PassRefPtr<Event> event)
     if (cursorToNotify)
         cursorToNotify->postSuccessHandlerCallback();
 
     if (cursorToNotify)
         cursorToNotify->postSuccessHandlerCallback();
 
-    if (m_transaction && event->type() != eventNames().blockedEvent) {
-        // If an error event and the default wasn't prevented...
-        if (dontPreventDefault && event->type() == eventNames().errorEvent) {
+    if (m_transaction) {
+        if (event->type() == eventNames().errorEvent && dontPreventDefault &&  !m_requestAborted) {
             m_transaction->setError(m_error);
             m_transaction->abort();
         }
             m_transaction->setError(m_error);
             m_transaction->abort();
         }
-        m_transaction->backend()->didCompleteTaskEvents();
-    }
 
 
-    if (m_transaction && m_readyState == DONE)
-        m_transaction->unregisterRequest(this);
+        if (event->type() != eventNames().blockedEvent)
+            m_transaction->backend()->didCompleteTaskEvents();
+
+        if (m_readyState == DONE)
+            m_transaction->unregisterRequest(this);
+    }
 
     return dontPreventDefault;
 }
 
 void IDBRequest::uncaughtExceptionInEventHandler()
 {
 
     return dontPreventDefault;
 }
 
 void IDBRequest::uncaughtExceptionInEventHandler()
 {
-    if (m_transaction)
-        m_transaction->backend()->abort();
+    if (m_transaction && !m_requestAborted) {
+        m_transaction->setError(DOMError::create(IDBDatabaseException::getErrorName(IDBDatabaseException::IDB_ABORT_ERR)));
+        m_transaction->abort();
+    }
 }
 
 void IDBRequest::enqueueEvent(PassRefPtr<Event> event)
 }
 
 void IDBRequest::enqueueEvent(PassRefPtr<Event> event)
index c09aa0e..5c2b0ec 100644 (file)
@@ -122,20 +122,6 @@ const String& IDBTransaction::mode() const
     return mode;
 }
 
     return mode;
 }
 
-IDBDatabase* IDBTransaction::db() const
-{
-    return m_database.get();
-}
-
-PassRefPtr<DOMError> IDBTransaction::error(ExceptionCode& ec) const
-{
-    if (m_state != Finished) {
-        ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
-        return 0;
-    }
-    return m_error;
-}
-
 void IDBTransaction::setError(PassRefPtr<DOMError> error)
 {
     ASSERT(m_state != Finished);
 void IDBTransaction::setError(PassRefPtr<DOMError> error)
 {
     ASSERT(m_state != Finished);
@@ -276,6 +262,9 @@ void IDBTransaction::onAbort()
     ASSERT(m_state != Finished);
 
     if (m_state != Finishing) {
     ASSERT(m_state != Finished);
 
     if (m_state != Finishing) {
+        // FIXME: Propagate true cause from back end (e.g. QuotaError, UnknownError, etc.)
+        setError(DOMError::create(IDBDatabaseException::getErrorName(IDBDatabaseException::UNKNOWN_ERR)));
+
         // Abort was not triggered by front-end, so outstanding requests must
         // be aborted now.
         while (!m_requestList.isEmpty()) {
         // Abort was not triggered by front-end, so outstanding requests must
         // be aborted now.
         while (!m_requestList.isEmpty()) {
index e5fba7c..3037862 100644 (file)
@@ -75,10 +75,8 @@ public:
 
     // Implement the IDBTransaction IDL
     const String& mode() const;
 
     // Implement the IDBTransaction IDL
     const String& mode() const;
-    IDBDatabase* db() const;
-    PassRefPtr<DOMError> error(ExceptionCode&) const;
-    void setError(PassRefPtr<DOMError>);
-
+    IDBDatabase* db() const { return m_database.get(); }
+    PassRefPtr<DOMError> error() const { return m_error; }
     PassRefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCode&);
     void abort();
 
     PassRefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCode&);
     void abort();
 
@@ -96,6 +94,7 @@ public:
     void objectStoreCreated(const String&, PassRefPtr<IDBObjectStore>);
     void objectStoreDeleted(const String&);
     void setActive(bool);
     void objectStoreCreated(const String&, PassRefPtr<IDBObjectStore>);
     void objectStoreDeleted(const String&);
     void setActive(bool);
+    void setError(PassRefPtr<DOMError>);
 
     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(complete);
 
     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(complete);
index a0e54c0..dfa9ed9 100644 (file)
@@ -39,13 +39,13 @@ module storage {
         // Properties
         readonly attribute DOMString mode;
         readonly attribute IDBDatabase db;
         // Properties
         readonly attribute DOMString mode;
         readonly attribute IDBDatabase db;
-        readonly attribute DOMError error 
-            getter raises (IDBDatabaseException);
+        readonly attribute DOMError error;
 
         // Methods
         IDBObjectStore objectStore (in DOMString name)
             raises (IDBDatabaseException);
         void abort ();
 
         // Methods
         IDBObjectStore objectStore (in DOMString name)
             raises (IDBDatabaseException);
         void abort ();
+
         // Events
         attribute EventListener onabort;
         attribute EventListener oncomplete;
         // Events
         attribute EventListener onabort;
         attribute EventListener oncomplete;