Skip to content

Commit

Permalink
Throw if not using Dexie.Promise from transaction scopes.
Browse files Browse the repository at this point in the history
This commit will hopefully help to find errors when using async / await or Promise.all() within transaction scopes.
Before this commit, those things could be done and the code seemed to work perfectly! The problem was that the transaction was not used. Instead it was executing the stuff transactionless, (each operation did its own transaction), wich is both slow and error prone.
  • Loading branch information
dfahlander committed Apr 5, 2016
1 parent 2d42749 commit 1214974
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
File renamed without changes.
10 changes: 7 additions & 3 deletions src/Dexie.js
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,13 @@ export default function Dexie(dbName, options) {
// Finally, call the scope function with our table and transaction arguments.
Promise._rootExec(function() {
returnValue = scopeFunc.apply(trans, tableArgs); // NOTE: returnValue is used in trans.on.complete() not as a returnValue to this func.
if (returnValue && typeof returnValue.next === 'function' && typeof returnValue.throw === 'function') {
// scopeFunc returned an iterable. Handle yield as await.
returnValue = awaitIterable(returnValue);
if (returnValue) {
if (typeof returnValue.next === 'function' && typeof returnValue.throw === 'function') {
// scopeFunc returned an iterable. Handle yield as await.
returnValue = awaitIterable(returnValue);
} else if (typeof returnValue.then === 'function' && (!returnValue.hasOwnProperty('_PSD'))) {
reject(stack(new exceptions.IncompatiblePromise()));
}
}
});
});
Expand Down
6 changes: 4 additions & 2 deletions src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ var dexieErrorNames = [
'SubTransaction',
'Unsupported',
'Internal',
'DatabaseClosed'
'DatabaseClosed',
'IncompatiblePromise'
];

var idbDomErrorNames = [
Expand All @@ -38,7 +39,8 @@ var errorList = dexieErrorNames.concat(idbDomErrorNames);

var defaultTexts = {
VersionChanged: "Database version changed by other database connection",
DatabaseClosed: "Database has been closed"
DatabaseClosed: "Database has been closed",
IncompatiblePromise: "Incompatible Promise used in transaction scope. See http://tinyurl.com/znyqjqc"
};

//
Expand Down
17 changes: 17 additions & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
}
},
"env": {
"browser": true
},
"rules": {
"no-undef": ["error"]
},
"globals": {
"Promise": true
}
}
17 changes: 17 additions & 0 deletions test/tests-transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Dexie from 'dexie';
import {module, stop, start, asyncTest, equal, ok} from 'QUnit';
import {resetDatabase} from './dexie-unittest-utils';

"use strict";

var db = new Dexie("TestDBTrans");
db.version(1).stores({
users: "username",
Expand All @@ -20,6 +22,21 @@ module("transaction", {
}
});

asyncTest("Transaction should fail if returning non-Dexie Promise in transaction scope", function(){
db.transaction('rw', db.users, function() {
return window.Promise.resolve().then(()=> {
ok(Dexie.currentTransaction == null, "Dexie.currentTransaction == null. If this assertion fails, don't weap. Rejoice and try to understand how the hell this could be possible.");
return db.users.add({ username: "foobar" });
}).then(()=>{
return db.users.add({ username: "barfoo" });
});
}).then (function(){
ok(false, "Transaction should not commit because we were using a non-Dexie promise");
}).catch ('IncompatiblePromiseError', function(e){
ok(true, "Good. Should fail with 'IncompatiblePromiseError': " + e);
}).finally(start);
});

asyncTest("empty transaction block", function () {
db.transaction('rw', db.users, db.pets, function () {
ok(true, "Entering transaction block but dont start any transaction");
Expand Down

0 comments on commit 1214974

Please sign in to comment.