diff --git a/assets/js/errors.js b/assets/js/errors.js index 7219e184af..d7bfaa7d6b 100644 --- a/assets/js/errors.js +++ b/assets/js/errors.js @@ -11,3 +11,10 @@ export class TimeoutError extends Error { this.name = 'TimeoutError'; } } + +export class HttpError extends Error { + constructor(message) { + super(message); + this.name = 'HttpError'; + } +} diff --git a/assets/js/helpers/ajax.js b/assets/js/helpers/ajax.js index bf69327b42..e4d64e7a8a 100644 --- a/assets/js/helpers/ajax.js +++ b/assets/js/helpers/ajax.js @@ -1,7 +1,7 @@ import formurlencoded from 'form-urlencoded'; import mergeDeepLeft from 'ramda/src/mergeDeepLeft.js'; import pipe from 'ramda/src/pipe.js'; -import { TimeoutError } from '../errors'; +import { HttpError, TimeoutError } from '../errors'; /** * Passing this function as a Promise handler will make the promise fail when the predicate is not true. @@ -10,7 +10,7 @@ export const rejectUnless = (pred) => (response) => { if (pred(response)) { return response; } else { - let err = new Error(response.statusText); + let err = new HttpError(response.statusText); err.response = response; throw err; } diff --git a/assets/js/selfoss-base.js b/assets/js/selfoss-base.js index c20c6cf834..2e422b942d 100644 --- a/assets/js/selfoss-base.js +++ b/assets/js/selfoss-base.js @@ -5,6 +5,7 @@ import { getInstanceInfo, login, logout } from './requests/common'; import * as itemsRequests from './requests/items'; import { getAllTags } from './requests/tags'; import * as ajax from './helpers/ajax'; +import { HttpError, TimeoutError } from './errors'; /** * base javascript application @@ -566,14 +567,14 @@ var selfoss = { selfoss.db.setOnline(); displayNextUnread(); }).catch(function(error) { - selfoss.handleAjaxError(error?.response?.status || 0).then(function() { + selfoss.handleAjaxError(error).then(function() { let statuses = ids.map(id => ({ entryId: id, name: 'unread', value: false })); selfoss.dbOffline.enqueueStatuses(statuses); - }).catch(function() { + }).catch(function(error) { content.html(articleList); selfoss.ui.refreshStreamButtons(true, hadMore); selfoss.ui.listReady(); @@ -583,7 +584,13 @@ var selfoss = { }, - handleAjaxError: function(httpCode, tryOffline = true) { + handleAjaxError: function(error, tryOffline = true) { + if (!(error instanceof HttpError || error instanceof TimeoutError)) { + throw error; + } + + const httpCode = error?.response?.status || 0; + if (tryOffline && httpCode != 403) { return selfoss.db.setOffline(); } else { @@ -591,7 +598,7 @@ var selfoss = { selfoss.ui.logout(); selfoss.ui.showLogin(selfoss.ui._('error_session_expired')); } - return Promise.reject(); + throw error; } }, diff --git a/assets/js/selfoss-db.js b/assets/js/selfoss-db.js index 3de1ec63fa..598a606a1e 100644 --- a/assets/js/selfoss-db.js +++ b/assets/js/selfoss-db.js @@ -228,7 +228,7 @@ selfoss.dbOnline = { } }).catch(function(error) { selfoss.dbOnline._syncDone(false); - selfoss.handleAjaxError(error?.response?.status || 0).catch(function() { + selfoss.handleAjaxError(error).catch(function(error) { selfoss.ui.showError(selfoss.ui._('error_sync') + ' ' + error.message); }); }).finally(function() { @@ -282,10 +282,10 @@ selfoss.dbOnline = { return; } - selfoss.handleAjaxError(error?.response?.status || 0).then(function() { + selfoss.handleAjaxError(error).then(function() { selfoss.dbOffline.reloadList(); selfoss.ui.afterReloadList(); - }).catch(() => { + }).catch(function(error) { selfoss.ui.showError(selfoss.ui._('error_loading') + ' ' + error.message); selfoss.events.entries(); selfoss.ui.refreshStreamButtons(); diff --git a/assets/js/selfoss-events-entriestoolbar.js b/assets/js/selfoss-events-entriestoolbar.js index 5980386a57..1ab4b6ac22 100644 --- a/assets/js/selfoss-events-entriestoolbar.js +++ b/assets/js/selfoss-events-entriestoolbar.js @@ -103,10 +103,10 @@ selfoss.events.entriesToolbar = function(parent) { itemsRequests.starr(id, starr).then(() => { selfoss.db.setOnline(); - }).catch((error) => { - selfoss.handleAjaxError(error?.response?.status || 0).then(function() { + }).catch(function(error) { + selfoss.handleAjaxError(error).then(function() { selfoss.dbOffline.enqueueStatus(id, 'starred', starr); - }).catch(function() { + }).catch(function(error) { // rollback ui changes selfoss.ui.entryStar(id, !starr); updateStats(!starr); @@ -151,10 +151,10 @@ selfoss.events.entriesToolbar = function(parent) { itemsRequests.mark(id, !unread).then(() => { selfoss.db.setOnline(); - }).catch((error) => { - selfoss.handleAjaxError(error?.response?.status || 0).then(function() { + }).catch(function(error) { + selfoss.handleAjaxError(error).then(function() { selfoss.dbOffline.enqueueStatus(id, 'unread', !unread); - }).catch(function() { + }).catch(function(error) { // rollback ui changes selfoss.ui.entryMark(id, unread); updateStats(!unread); diff --git a/assets/js/selfoss-events.js b/assets/js/selfoss-events.js index 54fb677712..840cad5405 100644 --- a/assets/js/selfoss-events.js +++ b/assets/js/selfoss-events.js @@ -213,7 +213,7 @@ selfoss.events = { return; } - selfoss.handleAjaxError(error?.response?.status || 0, false).catch(function() { + selfoss.handleAjaxError(error, false).catch(function(error) { selfoss.ui.showError(selfoss.ui._('error_loading') + ' ' + error.message); }); }).finally(() => {