소스 검색

Improve IndexedDB error handling

Thibaut Courouble 8 년 전
부모
커밋
d63aadb27e
3개의 변경된 파일32개의 추가작업 그리고 23개의 파일을 삭제
  1. 18 12
      assets/javascripts/app/db.coffee
  2. 13 10
      assets/javascripts/templates/error_tmpl.coffee
  3. 1 1
      assets/javascripts/views/content/offline_page.coffee

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

@@ -17,8 +17,8 @@ class app.DB
       req.onsuccess = @onOpenSuccess
       req.onsuccess = @onOpenSuccess
       req.onerror = @onOpenError
       req.onerror = @onOpenError
       req.onupgradeneeded = @onUpgradeNeeded
       req.onupgradeneeded = @onUpgradeNeeded
-    catch
-      @onOpenError()
+    catch error
+      @fail 'error', error
     return
     return
 
 
   onOpenSuccess: (event) =>
   onOpenSuccess: (event) =>
@@ -26,18 +26,16 @@ class app.DB
 
 
     if db.objectStoreNames.length is 0
     if db.objectStoreNames.length is 0
       try db.close()
       try db.close()
-      @reason = 'empty'
-      @onOpenError()
+      @fail 'empty'
       return
       return
 
 
     unless @checkedBuggyIDB
     unless @checkedBuggyIDB
       @checkedBuggyIDB = true
       @checkedBuggyIDB = true
       try
       try
         @idbTransaction(db, stores: $.makeArray(db.objectStoreNames)[0..1], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
         @idbTransaction(db, stores: $.makeArray(db.objectStoreNames)[0..1], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
-      catch
+      catch error
         try db.close()
         try db.close()
-        @reason = 'apple'
-        @onOpenError()
+        @fail 'buggy', error
         return
         return
 
 
     @runCallbacks(db)
     @runCallbacks(db)
@@ -46,17 +44,25 @@ class app.DB
     return
     return
 
 
   onOpenError: (event) =>
   onOpenError: (event) =>
-    event?.preventDefault()
+    event.preventDefault()
     @open = false
     @open = false
+    error = event.target.error
 
 
-    if event?.target?.error?.name is 'QuotaExceededError'
+    if error.name is 'QuotaExceededError'
       @reset()
       @reset()
       @db()
       @db()
       app.onQuotaExceeded()
       app.onQuotaExceeded()
     else
     else
-      @useIndexedDB = false
-      @reason or= 'cant_open'
-      @runCallbacks()
+      @fail 'cant_open', error
+    return
+
+  fail: (reason, error) ->
+    @useIndexedDB = false
+    @reason or= reason
+    @error or= error
+    console.error? 'IDB error', error if error
+    @runCallbacks()
+    Raven.captureException error, level: 'warning' if error
     return
     return
 
 
   runCallbacks: (db) ->
   runCallbacks: (db) ->

+ 13 - 10
assets/javascripts/templates/error_tmpl.coffee

@@ -22,25 +22,28 @@ app.templates.bootError = ->
         """ Check your Internet connection and try <a href="#" data-behavior="reload">reloading</a>.<br>
         """ Check your Internet connection and try <a href="#" data-behavior="reload">reloading</a>.<br>
             If you keep seeing this, you're likely behind a proxy or firewall that blocks cross-domain requests. """
             If you keep seeing this, you're likely behind a proxy or firewall that blocks cross-domain requests. """
 
 
-app.templates.offlineError = (reason) ->
+app.templates.offlineError = (reason, exception) ->
   if reason is 'cookie_blocked'
   if reason is 'cookie_blocked'
     return error """ Cookies must be enabled to use offline mode. """
     return error """ Cookies must be enabled to use offline mode. """
 
 
   reason = switch reason
   reason = switch reason
     when 'not_supported'
     when 'not_supported'
-      """ Unfortunately your browser either doesn't support IndexedDB or does not make it available. """
+      """ DevDocs requires IndexedDB to cache documentations for offline access.<br>
+          Unfortunately your browser either doesn't support IndexedDB or doesn't make it available. """
+    when 'buggy'
+      """ DevDocs requires IndexedDB to cache documentations for offline access.<br>
+          Unfortunately your browser's implementation of IndexedDB contains bugs that prevent DevDocs from using it. """
+    when 'exception'
+      """ An error occured when trying to open the IndexedDB database:<br>
+          <code class="_label">#{exception.name}: #{exception.message}</code> """
     when 'cant_open'
     when 'cant_open'
-      """ Although your browser supports IndexedDB, DevDocs couldn't open the database.<br>
+      """ An error occured when trying to open the IndexedDB database:<br>
+          <code class="_label">#{exception.name}: #{exception.message}</code><br>
           This could be because you're browsing in private mode or have disallowed offline storage on the domain. """
           This could be because you're browsing in private mode or have disallowed offline storage on the domain. """
     when 'empty'
     when 'empty'
-      """ Although your browser supports IndexedDB, DevDocs couldn't properly set up the database.<br>
-          This could be because the database is corrupted. Try <a href="#" data-behavior="reset">resetting the app</a>. """
-    when 'apple'
-      """ Unfortunately Safari's implementation of IndexedDB is <a href="https://bugs.webkit.org/show_bug.cgi?id=136937">badly broken</a>.<br>
-          This message will automatically go away when Apple fix their code. """
+      """ The IndexedDB database appears to be corrupted. Try <a href="#" data-behavior="reset">resetting the app</a>. """
 
 
-  error """ Offline mode is unavailable. """,
-        """ DevDocs requires IndexedDB to cache documentations for offline access.<br>#{reason} """
+  error 'Offline mode is unavailable.', reason
 
 
 app.templates.unsupportedBrowser = """
 app.templates.unsupportedBrowser = """
   <div class="_fail">
   <div class="_fail">

+ 1 - 1
assets/javascripts/views/content/offline_page.coffee

@@ -18,7 +18,7 @@ class app.views.OfflinePage extends app.View
     app.docs.getInstallStatuses (statuses) =>
     app.docs.getInstallStatuses (statuses) =>
       return unless @activated
       return unless @activated
       if statuses is false
       if statuses is false
-        @html @tmpl('offlineError', app.db.reason)
+        @html @tmpl('offlineError', app.db.reason, app.db.error)
       else
       else
         html = ''
         html = ''
         html += @renderDoc(doc, statuses[doc.slug]) for doc in app.docs.all()
         html += @renderDoc(doc, statuses[doc.slug]) for doc in app.docs.all()