Browse Source

Move legacy Ajax error handling logic to the bundle

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
tags/v17.0.0beta1
Christoph Wurst 5 years ago
parent
commit
ab72bd64f5
No account linked to committer's email address
7 changed files with 142 additions and 141 deletions
  1. 7
    27
      core/js/dist/login.js
  2. 1
    1
      core/js/dist/login.js.map
  3. 6
    26
      core/js/dist/main.js
  4. 1
    1
      core/js/dist/main.js.map
  5. 0
    86
      core/js/js.js
  6. 13
    0
      core/src/OC/index.js
  7. 114
    0
      core/src/OC/xhr-error.js

+ 7
- 27
core/js/dist/login.js
File diff suppressed because it is too large
View File


+ 1
- 1
core/js/dist/login.js.map
File diff suppressed because it is too large
View File


+ 6
- 26
core/js/dist/main.js
File diff suppressed because it is too large
View File


+ 1
- 1
core/js/dist/main.js.map
File diff suppressed because it is too large
View File


+ 0
- 86
core/js/js.js View File

@@ -5,91 +5,5 @@ Object.assign(window.OC, {
/* jshint camelcase: false */

/**
* Warn users that the connection to the server was lost temporarily
*
* This function is throttled to prevent stacked notfications.
* After 7sec the first notification is gone, then we can show another one
* if necessary.
*/
_ajaxConnectionLostHandler: _.throttle(function() {
OC.Notification.showTemporary(t('core', 'Connection to server lost'));
}, 7 * 1000, {trailing: false}),

/**
* Process ajax error, redirects to main page
* if an error/auth error status was returned.
*/
_processAjaxError: function(xhr) {
var self = this;
// purposefully aborted request ?
// this._userIsNavigatingAway needed to distinguish ajax calls cancelled by navigating away
// from calls cancelled by failed cross-domain ajax due to SSO redirect
if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout' || self._reloadCalled)) {
return;
}

if (_.contains([302, 303, 307, 401], xhr.status) && OC.currentUser) {
// sometimes "beforeunload" happens later, so need to defer the reload a bit
setTimeout(function() {
if (!self._userIsNavigatingAway && !self._reloadCalled) {
var timer = 0;
var seconds = 5;
var interval = setInterval( function() {
OC.Notification.showUpdate(n('core', 'Problem loading page, reloading in %n second', 'Problem loading page, reloading in %n seconds', seconds - timer));
if (timer >= seconds) {
clearInterval(interval);
OC.reload();
}
timer++;
}, 1000 // 1 second interval
);

// only call reload once
self._reloadCalled = true;
}
}, 100);
} else if(xhr.status === 0) {
// Connection lost (e.g. WiFi disconnected or server is down)
setTimeout(function() {
if (!self._userIsNavigatingAway && !self._reloadCalled) {
self._ajaxConnectionLostHandler();
}
}, 100);
}
},

/**
* Registers XmlHttpRequest object for global error processing.
*
* This means that if this XHR object returns 401 or session timeout errors,
* the current page will automatically be reloaded.
*
* @param {XMLHttpRequest} xhr
*/
registerXHRForErrorProcessing: function(xhr) {
var loadCallback = function() {
if (xhr.readyState !== 4) {
return;
}

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
return;
}

// fire jquery global ajax error handler
$(document).trigger(new $.Event('ajaxError'), xhr);
};

var errorCallback = function() {
// fire jquery global ajax error handler
$(document).trigger(new $.Event('ajaxError'), xhr);
};

if (xhr.addEventListener) {
xhr.addEventListener('load', loadCallback);
xhr.addEventListener('error', errorCallback);
}

}
});


+ 13
- 0
core/src/OC/index.js View File

@@ -20,6 +20,11 @@
*/

import {addScript, addStyle} from './legacy-loader'
import {
ajaxConnectionLostHandler,
processAjaxError,
registerXHRForErrorProcessing,
} from './xhr-error'
import Apps from './apps'
import {AppConfig, appConfig} from './appconfig'
import {appSettings} from './appsettings'
@@ -154,6 +159,14 @@ export default {
isUserAdmin,
L10N,

/**
* Ajax error handlers
* @todo remove from here and keep internally -> requires new tests
*/
_ajaxConnectionLostHandler: ajaxConnectionLostHandler,
_processAjaxError: processAjaxError,
registerXHRForErrorProcessing,

/**
* Capabilities
*

+ 114
- 0
core/src/OC/xhr-error.js View File

@@ -0,0 +1,114 @@
/*
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import _ from 'underscore'
import $ from 'jquery'

import OC from './index'
import Notification from './notification'

/**
* Warn users that the connection to the server was lost temporarily
*
* This function is throttled to prevent stacked notfications.
* After 7sec the first notification is gone, then we can show another one
* if necessary.
*/
export const ajaxConnectionLostHandler = _.throttle(() => {
Notification.showTemporary(t('core', 'Connection to server lost'))
}, 7 * 1000, {trailing: false})

/**
* Process ajax error, redirects to main page
* if an error/auth error status was returned.
*/
export const processAjaxError = xhr => {
// purposefully aborted request ?
// OC._userIsNavigatingAway needed to distinguish ajax calls cancelled by navigating away
// from calls cancelled by failed cross-domain ajax due to SSO redirect
if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout' || OC._reloadCalled)) {
return
}

if (_.contains([302, 303, 307, 401], xhr.status) && OC.currentUser) {
// sometimes "beforeunload" happens later, so need to defer the reload a bit
setTimeout(function () {
if (!OC._userIsNavigatingAway && !OC._reloadCalled) {
let timer = 0
const seconds = 5
const interval = setInterval(function () {
Notification.showUpdate(n('core', 'Problem loading page, reloading in %n second', 'Problem loading page, reloading in %n seconds', seconds - timer))
if (timer >= seconds) {
clearInterval(interval)
OC.reload()
}
timer++
}, 1000 // 1 second interval
)

// only call reload once
OC._reloadCalled = true
}
}, 100)
} else if (xhr.status === 0) {
// Connection lost (e.g. WiFi disconnected or server is down)
setTimeout(function () {
if (!OC._userIsNavigatingAway && !OC._reloadCalled) {
// TODO: call method above directly
OC._ajaxConnectionLostHandler()
}
}, 100)
}
}

/**
* Registers XmlHttpRequest object for global error processing.
*
* This means that if this XHR object returns 401 or session timeout errors,
* the current page will automatically be reloaded.
*
* @param {XMLHttpRequest} xhr
*/
export const registerXHRForErrorProcessing = xhr => {
const loadCallback = () => {
if (xhr.readyState !== 4) {
return
}

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
return
}

// fire jquery global ajax error handler
$(document).trigger(new $.Event('ajaxError'), xhr)
}

const errorCallback = () => {
// fire jquery global ajax error handler
$(document).trigger(new $.Event('ajaxError'), xhr)
}

if (xhr.addEventListener) {
xhr.addEventListener('load', loadCallback)
xhr.addEventListener('error', errorCallback)
}

}

Loading…
Cancel
Save