From d63aadb27e9d8f13e1366109c5806f7821abb1c5 Mon Sep 17 00:00:00 2001 From: Thibaut Courouble Date: Sun, 5 Mar 2017 16:38:43 -0500 Subject: [PATCH] Improve IndexedDB error handling --- assets/javascripts/app/db.coffee | 30 +++++++++++-------- .../javascripts/templates/error_tmpl.coffee | 23 +++++++------- .../views/content/offline_page.coffee | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/assets/javascripts/app/db.coffee b/assets/javascripts/app/db.coffee index da0b55b3..75688682 100644 --- a/assets/javascripts/app/db.coffee +++ b/assets/javascripts/app/db.coffee @@ -17,8 +17,8 @@ class app.DB req.onsuccess = @onOpenSuccess req.onerror = @onOpenError req.onupgradeneeded = @onUpgradeNeeded - catch - @onOpenError() + catch error + @fail 'error', error return onOpenSuccess: (event) => @@ -26,18 +26,16 @@ class app.DB if db.objectStoreNames.length is 0 try db.close() - @reason = 'empty' - @onOpenError() + @fail 'empty' return unless @checkedBuggyIDB @checkedBuggyIDB = true try @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() - @reason = 'apple' - @onOpenError() + @fail 'buggy', error return @runCallbacks(db) @@ -46,17 +44,25 @@ class app.DB return onOpenError: (event) => - event?.preventDefault() + event.preventDefault() @open = false + error = event.target.error - if event?.target?.error?.name is 'QuotaExceededError' + if error.name is 'QuotaExceededError' @reset() @db() app.onQuotaExceeded() 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 runCallbacks: (db) -> diff --git a/assets/javascripts/templates/error_tmpl.coffee b/assets/javascripts/templates/error_tmpl.coffee index a6a8e974..e0dfef55 100644 --- a/assets/javascripts/templates/error_tmpl.coffee +++ b/assets/javascripts/templates/error_tmpl.coffee @@ -22,25 +22,28 @@ app.templates.bootError = -> """ Check your Internet connection and try reloading.
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' return error """ Cookies must be enabled to use offline mode. """ reason = switch reason 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.
+ 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.
+ 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:
+ #{exception.name}: #{exception.message} """ when 'cant_open' - """ Although your browser supports IndexedDB, DevDocs couldn't open the database.
+ """ An error occured when trying to open the IndexedDB database:
+ #{exception.name}: #{exception.message}
This could be because you're browsing in private mode or have disallowed offline storage on the domain. """ when 'empty' - """ Although your browser supports IndexedDB, DevDocs couldn't properly set up the database.
- This could be because the database is corrupted. Try resetting the app. """ - when 'apple' - """ Unfortunately Safari's implementation of IndexedDB is badly broken.
- This message will automatically go away when Apple fix their code. """ + """ The IndexedDB database appears to be corrupted. Try resetting the app. """ - error """ Offline mode is unavailable. """, - """ DevDocs requires IndexedDB to cache documentations for offline access.
#{reason} """ + error 'Offline mode is unavailable.', reason app.templates.unsupportedBrowser = """
diff --git a/assets/javascripts/views/content/offline_page.coffee b/assets/javascripts/views/content/offline_page.coffee index 22859f5a..97cae8d4 100644 --- a/assets/javascripts/views/content/offline_page.coffee +++ b/assets/javascripts/views/content/offline_page.coffee @@ -18,7 +18,7 @@ class app.views.OfflinePage extends app.View app.docs.getInstallStatuses (statuses) => return unless @activated if statuses is false - @html @tmpl('offlineError', app.db.reason) + @html @tmpl('offlineError', app.db.reason, app.db.error) else html = '' html += @renderDoc(doc, statuses[doc.slug]) for doc in app.docs.all()