Browse Source

Improve IndexedDB error handling

Thibaut 11 years ago
parent
commit
58a463d3d7
1 changed files with 34 additions and 12 deletions
  1. 34 12
      assets/javascripts/app/db.coffee

+ 34 - 12
assets/javascripts/app/db.coffee

@@ -25,7 +25,7 @@ class app.DB
     try
     try
       db = event.target.result
       db = event.target.result
       unless @checkedBuggyIDB
       unless @checkedBuggyIDB
-        db.transaction(['docs', app.docs.all()[0].slug], 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
+        @idbTransaction(db, stores: ['docs', app.docs.all()[0].slug], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
         @checkedBuggyIDB = true
         @checkedBuggyIDB = true
     catch
     catch
       try db.close()
       try db.close()
@@ -66,10 +66,14 @@ class app.DB
         onError()
         onError()
         return
         return
 
 
-      txn = db.transaction ['docs', doc.slug], 'readwrite'
+      txn = @idbTransaction db, stores: ['docs', doc.slug], mode: 'readwrite', ignoreError: false
       txn.oncomplete = =>
       txn.oncomplete = =>
         @cachedDocs?[doc.slug] = doc.mtime
         @cachedDocs?[doc.slug] = doc.mtime
-        if txn.error then onError() else onSuccess()
+        onSuccess()
+        return
+      txn.onerror = (event) ->
+        event.preventDefault()
+        onError(event)
         return
         return
 
 
       store = txn.objectStore(doc.slug)
       store = txn.objectStore(doc.slug)
@@ -87,10 +91,14 @@ class app.DB
         onError()
         onError()
         return
         return
 
 
-      txn = db.transaction ['docs', doc.slug], 'readwrite'
+      txn = @idbTransaction db, stores: ['docs', doc.slug], mode: 'readwrite', ignoreError: false
       txn.oncomplete = =>
       txn.oncomplete = =>
         delete @cachedDocs?[doc.slug]
         delete @cachedDocs?[doc.slug]
-        if txn.error then onError() else onSuccess()
+        onSuccess()
+        return
+      txn.onerror = (event) ->
+        event.preventDefault()
+        onError(event)
         return
         return
 
 
       store = txn.objectStore(doc.slug)
       store = txn.objectStore(doc.slug)
@@ -106,12 +114,12 @@ class app.DB
       fn(version)
       fn(version)
       return
       return
 
 
-    @db (db) ->
+    @db (db) =>
       unless db
       unless db
         fn(false)
         fn(false)
         return
         return
 
 
-      txn = db.transaction ['docs'], 'readonly'
+      txn = @idbTransaction db, stores: ['docs'], mode: 'readonly'
       store = txn.objectStore('docs')
       store = txn.objectStore('docs')
 
 
       req = store.get(doc.slug)
       req = store.get(doc.slug)
@@ -134,13 +142,15 @@ class app.DB
       fn(versions)
       fn(versions)
       return
       return
 
 
-    @db (db) ->
+    @db (db) =>
       unless db
       unless db
         fn(false)
         fn(false)
         return
         return
 
 
-      txn = db.transaction ['docs'], 'readonly'
-      txn.oncomplete = -> fn(result)
+      txn = @idbTransaction db, stores: ['docs'], mode: 'readonly'
+      txn.oncomplete = ->
+        fn(result)
+        return
       store = txn.objectStore('docs')
       store = txn.objectStore('docs')
       result = {}
       result = {}
 
 
@@ -182,7 +192,7 @@ class app.DB
         onError()
         onError()
         return
         return
 
 
-      txn = db.transaction [entry.doc.slug], 'readonly'
+      txn = @idbTransaction db, stores: [entry.doc.slug], mode: 'readonly'
       store = txn.objectStore(entry.doc.slug)
       store = txn.objectStore(entry.doc.slug)
 
 
       req = store.get(entry.dbPath())
       req = store.get(entry.dbPath())
@@ -199,7 +209,7 @@ class app.DB
   loadDocsCache: (db) ->
   loadDocsCache: (db) ->
     @cachedDocs = {}
     @cachedDocs = {}
 
 
-    txn = db.transaction ['docs'], 'readonly'
+    txn = @idbTransaction db, stores: ['docs'], mode: 'readonly'
     store = txn.objectStore('docs')
     store = txn.objectStore('docs')
 
 
     req = store.openCursor()
     req = store.openCursor()
@@ -216,6 +226,18 @@ class app.DB
   shouldLoadWithIDB: (entry) ->
   shouldLoadWithIDB: (entry) ->
     @useIndexedDB and (not @cachedDocs or @cachedDocs[entry.doc.slug])
     @useIndexedDB and (not @cachedDocs or @cachedDocs[entry.doc.slug])
 
 
+  idbTransaction: (db, options) ->
+    txn = db.transaction(options.stores, options.mode)
+    unless options.ignoreError is false
+      txn.onerror = (event) ->
+        event.preventDefault()
+        return
+    unless options.ignoreAbort is false
+      txn.onabort = (event) ->
+        event.preventDefault()
+        return
+    txn
+
   reset: ->
   reset: ->
     try indexedDB?.deleteDatabase(NAME) catch
     try indexedDB?.deleteDatabase(NAME) catch
     return
     return