Add handler for global ajax errors
This commit is contained in:
parent
294dcb4eff
commit
b8b77709c0
|
@ -1427,13 +1427,6 @@
|
||||||
delete this._reloadCall;
|
delete this._reloadCall;
|
||||||
this.hideMask();
|
this.hideMask();
|
||||||
|
|
||||||
if (status === 401) {
|
|
||||||
// TODO: append current URL to be able to get back after logging in again
|
|
||||||
OC.redirect(OC.generateUrl('apps/files'));
|
|
||||||
OC.Notification.show(result);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Firewall Blocked request?
|
// Firewall Blocked request?
|
||||||
if (status === 403) {
|
if (status === 403) {
|
||||||
// Go home
|
// Go home
|
||||||
|
|
|
@ -2441,13 +2441,6 @@ describe('OCA.Files.FileList tests', function() {
|
||||||
getFolderContentsStub.restore();
|
getFolderContentsStub.restore();
|
||||||
fileList = undefined;
|
fileList = undefined;
|
||||||
});
|
});
|
||||||
it('redirects to files app in case of auth error', function () {
|
|
||||||
deferredList.reject(401, 'Authentication error');
|
|
||||||
|
|
||||||
expect(redirectStub.calledOnce).toEqual(true);
|
|
||||||
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files');
|
|
||||||
expect(getFolderContentsStub.calledOnce).toEqual(true);
|
|
||||||
});
|
|
||||||
it('redirects to root folder in case of forbidden access', function () {
|
it('redirects to root folder in case of forbidden access', function () {
|
||||||
deferredList.reject(403);
|
deferredList.reject(403);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,8 @@
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OC.registerXHRForErrorProcessing(xhr);
|
||||||
return xhr;
|
return xhr;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,13 @@ var OC={
|
||||||
window.location = targetURL;
|
window.location = targetURL;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the current page
|
||||||
|
*/
|
||||||
|
reload: function() {
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol that is used to access this ownCloud instance
|
* Protocol that is used to access this ownCloud instance
|
||||||
* @return {string} Used protocol
|
* @return {string} Used protocol
|
||||||
|
@ -727,6 +734,56 @@ var OC={
|
||||||
isUserAdmin: function() {
|
isUserAdmin: function() {
|
||||||
return oc_isadmin;
|
return oc_isadmin;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process ajax error, redirects to main page
|
||||||
|
* if an error/auth error status was returned.
|
||||||
|
*/
|
||||||
|
_processAjaxError: function(xhr) {
|
||||||
|
// purposefully aborted request ?
|
||||||
|
if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.contains([0, 302, 307, 401], xhr.status)) {
|
||||||
|
OC.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: also needs an IE8 way
|
||||||
|
if (xhr.addEventListener) {
|
||||||
|
xhr.addEventListener('load', loadCallback);
|
||||||
|
xhr.addEventListener('error', errorCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1311,11 +1368,11 @@ function initCore() {
|
||||||
$('html').addClass('edge');
|
$('html').addClass('edge');
|
||||||
}
|
}
|
||||||
|
|
||||||
$( document ).ajaxError(function( event, request, settings ) {
|
$(document).on('ajaxError.main', function( event, request, settings ) {
|
||||||
if (_.contains([302, 307, 401], request.status)) {
|
if (settings && settings.allowAuthErrors) {
|
||||||
var app = $('#content').attr('class').substring(4);
|
return;
|
||||||
OC.redirect(OC.generateUrl('apps/' + app));
|
|
||||||
}
|
}
|
||||||
|
OC._processAjaxError(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,7 +40,8 @@
|
||||||
'<d:propfind xmlns:d="DAV:">' +
|
'<d:propfind xmlns:d="DAV:">' +
|
||||||
'<d:prop><d:resourcetype/></d:prop>' +
|
'<d:prop><d:resourcetype/></d:prop>' +
|
||||||
'</d:propfind>',
|
'</d:propfind>',
|
||||||
complete: afterCall
|
complete: afterCall,
|
||||||
|
allowAuthErrors: true
|
||||||
});
|
});
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
},
|
},
|
||||||
|
@ -157,7 +158,8 @@
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.generateUrl('settings/ajax/checksetup')
|
url: OC.generateUrl('settings/ajax/checksetup'),
|
||||||
|
allowAuthErrors: true
|
||||||
}).then(afterCall, afterCall);
|
}).then(afterCall, afterCall);
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
},
|
},
|
||||||
|
@ -181,7 +183,8 @@
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.generateUrl('heartbeat')
|
url: OC.generateUrl('heartbeat'),
|
||||||
|
allowAuthErrors: true
|
||||||
}).then(afterCall, afterCall);
|
}).then(afterCall, afterCall);
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
|
|
|
@ -116,7 +116,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
|
||||||
// global setup for all tests
|
// global setup for all tests
|
||||||
(function setupTests() {
|
(function setupTests() {
|
||||||
var fakeServer = null,
|
var fakeServer = null,
|
||||||
$testArea = null;
|
$testArea = null,
|
||||||
|
ajaxErrorStub = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility functions for testing
|
* Utility functions for testing
|
||||||
|
@ -162,6 +163,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
|
||||||
|
|
||||||
// dummy select2 (which isn't loaded during the tests)
|
// dummy select2 (which isn't loaded during the tests)
|
||||||
$.fn.select2 = function() { return this; };
|
$.fn.select2 = function() { return this; };
|
||||||
|
|
||||||
|
ajaxErrorStub = sinon.stub(OC, '_processAjaxError');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
|
@ -172,6 +175,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
|
||||||
$testArea.remove();
|
$testArea.remove();
|
||||||
|
|
||||||
delete($.fn.select2);
|
delete($.fn.select2);
|
||||||
|
|
||||||
|
ajaxErrorStub.restore();
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,7 @@ describe('Core base tests', function() {
|
||||||
/* jshint camelcase: false */
|
/* jshint camelcase: false */
|
||||||
window.oc_config = oldConfig;
|
window.oc_config = oldConfig;
|
||||||
routeStub.restore();
|
routeStub.restore();
|
||||||
|
$(document).off('ajaxError');
|
||||||
});
|
});
|
||||||
it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
|
it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
|
||||||
/* jshint camelcase: false */
|
/* jshint camelcase: false */
|
||||||
|
@ -473,6 +474,7 @@ describe('Core base tests', function() {
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
clock.restore();
|
clock.restore();
|
||||||
|
$(document).off('ajaxError');
|
||||||
});
|
});
|
||||||
it('Sets up menu toggle', function() {
|
it('Sets up menu toggle', function() {
|
||||||
window.initCore();
|
window.initCore();
|
||||||
|
@ -841,5 +843,45 @@ describe('Core base tests', function() {
|
||||||
// verification is done in afterEach
|
// verification is done in afterEach
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('global ajax errors', function() {
|
||||||
|
var reloadStub, ajaxErrorStub;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
reloadStub = sinon.stub(OC, 'reload');
|
||||||
|
// unstub the error processing method
|
||||||
|
ajaxErrorStub = OC._processAjaxError;
|
||||||
|
ajaxErrorStub.restore();
|
||||||
|
window.initCore();
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
reloadStub.restore();
|
||||||
|
$(document).off('ajaxError');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reloads current page in case of auth error', function () {
|
||||||
|
var dataProvider = [
|
||||||
|
[200, false],
|
||||||
|
[400, false],
|
||||||
|
[401, true],
|
||||||
|
[302, true],
|
||||||
|
[307, true]
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < dataProvider.length; i++) {
|
||||||
|
var xhr = { status: dataProvider[i][0] };
|
||||||
|
var expectedCall = dataProvider[i][1];
|
||||||
|
|
||||||
|
reloadStub.reset();
|
||||||
|
|
||||||
|
$(document).trigger(new $.Event('ajaxError'), xhr);
|
||||||
|
|
||||||
|
if (expectedCall) {
|
||||||
|
expect(reloadStub.calledOnce).toEqual(true);
|
||||||
|
} else {
|
||||||
|
expect(reloadStub.notCalled).toEqual(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue