Merge pull request #57642 from nextcloud/chore/xhr

chore: drop duplicated legacy Ajax error handling
This commit is contained in:
Ferdinand Thiessen 2026-01-19 17:09:46 +01:00 committed by GitHub
commit 772471da4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 18 additions and 157 deletions

View file

@ -73,11 +73,6 @@ import Settings from './settings.js'
import { theme } from './theme.js'
import Util from './util.js'
import webroot from './webroot.js'
import {
ajaxConnectionLostHandler,
processAjaxError,
registerXHRForErrorProcessing,
} from './xhr-error.js'
/** @namespace OC */
export default {
@ -125,13 +120,11 @@ export default {
L10N,
/**
* Ajax error handlers
* This is already handled by `interceptRequests` in `core/src/init.js`.
*
* @todo remove from here and keep internally -> requires new tests
* @deprecated 33.0.0 - unused by Nextcloud and only a stub remains. Just remove usage.
*/
_ajaxConnectionLostHandler: ajaxConnectionLostHandler,
_processAjaxError: processAjaxError,
registerXHRForErrorProcessing,
registerXHRForErrorProcessing: () => {},
/**
* Capabilities

View file

@ -1,102 +0,0 @@
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCurrentUser } from '@nextcloud/auth'
import { showWarning } from '@nextcloud/dialogs'
import $ from 'jquery'
import _ from 'underscore'
import OC from './index.js'
import Notification from './notification.js'
/**
* Warn users that the connection to the server was lost temporarily
*
* This function is throttled to prevent stacked notifications.
* After 7sec the first notification is gone, then we can show another one
* if necessary.
*/
export const ajaxConnectionLostHandler = _.throttle(() => {
showWarning(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.
*
* @param {XMLHttpRequest} xhr xhr request
*/
export function 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 ([302, 303, 307, 401].includes(xhr.status) && getCurrentUser()) {
// 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)
window.location.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 xhr request
*/
export function 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)
}
}

View file

@ -67,36 +67,6 @@ export function initCore() {
interceptRequests()
initFallbackClipboardAPI()
$(window).on('unload.main', () => {
OC._unloadCalled = true
})
$(window).on('beforeunload.main', () => {
// super-trick thanks to http://stackoverflow.com/a/4651049
// in case another handler displays a confirmation dialog (ex: navigating away
// during an upload), there are two possible outcomes: user clicked "ok" or
// "cancel"
// first timeout handler is called after unload dialog is closed
setTimeout(() => {
OC._userIsNavigatingAway = true
// second timeout event is only called if user cancelled (Chrome),
// but in other browsers it might still be triggered, so need to
// set a higher delay...
setTimeout(() => {
if (!OC._unloadCalled) {
OC._userIsNavigatingAway = false
}
}, 10000)
}, 1)
})
$(document).on('ajaxError.main', function(event, request, settings) {
if (settings && settings.allowAuthErrors) {
return
}
OC._processAjaxError(request)
})
initSessionHeartBeat()
OC.registerMenu($('#expand'), $('#expanddiv'), false, true)

4
dist/7883-7883.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/core-login.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/core-main.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
(()=>{"use strict";var e,r,t,o={47210(e,r,t){var o=t(21777);t.nc=(0,o.aV)(),window.TESTING||OC?.config?.no_unsupported_browser_warning||window.addEventListener("DOMContentLoaded",async function(){const{testSupportedBrowser:e}=await Promise.all([t.e(4208),t.e(7883)]).then(t.bind(t,77883));e()})}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var t=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=o,e=[],a.O=(r,t,o,n)=>{if(!t){var i=1/0;for(s=0;s<e.length;s++){for(var[t,o,n]=e[s],l=!0,d=0;d<t.length;d++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[d]))?t.splice(d--,1):(l=!1,n<i&&(i=n));if(l){e.splice(s--,1);var c=o();void 0!==c&&(r=c)}}return r}n=n||0;for(var s=e.length;s>0&&e[s-1][2]>n;s--)e[s]=e[s-1];e[s]=[t,o,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce((r,t)=>(a.f[t](e,r),r),[])),a.u=e=>e+"-"+e+".js?v=e12830427019df1566c5",a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="nextcloud-ui-legacy:",a.l=(e,o,n,i)=>{if(r[e])r[e].push(o);else{var l,d;if(void 0!==n)for(var c=document.getElementsByTagName("script"),s=0;s<c.length;s++){var u=c[s];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==t+n){l=u;break}}l||(d=!0,(l=document.createElement("script")).charset="utf-8",a.nc&&l.setAttribute("nonce",a.nc),l.setAttribute("data-webpack",t+n),l.src=e),r[e]=[o];var p=(t,o)=>{l.onerror=l.onload=null,clearTimeout(f);var n=r[e];if(delete r[e],l.parentNode&&l.parentNode.removeChild(l),n&&n.forEach(e=>e(o)),t)return t(o)},f=setTimeout(p.bind(null,void 0,{type:"timeout",target:l}),12e4);l.onerror=p.bind(null,l.onerror),l.onload=p.bind(null,l.onload),d&&document.head.appendChild(l)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.j=3604,(()=>{var e;globalThis.importScripts&&(e=globalThis.location+"");var r=globalThis.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&(!e||!/^http(s?):/.test(e));)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={3604:0};a.f.j=(r,t)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else{var n=new Promise((t,n)=>o=e[r]=[t,n]);t.push(o[2]=n);var i=a.p+a.u(r),l=new Error;a.l(i,t=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var n=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;l.message="Loading chunk "+r+" failed.\n("+n+": "+i+")",l.name="ChunkLoadError",l.type=n,l.request=i,o[1](l)}},"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var o,n,[i,l,d]=t,c=0;if(i.some(r=>0!==e[r])){for(o in l)a.o(l,o)&&(a.m[o]=l[o]);if(d)var s=d(a)}for(r&&r(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(s)},t=globalThis.webpackChunknextcloud_ui_legacy=globalThis.webpackChunknextcloud_ui_legacy||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0;var i=a.O(void 0,[4208],()=>a(47210));i=a.O(i)})();
//# sourceMappingURL=core-unsupported-browser-redirect.js.map?v=38df1732707e19f12f35
(()=>{"use strict";var e,r,t,o={47210(e,r,t){var o=t(21777);t.nc=(0,o.aV)(),window.TESTING||OC?.config?.no_unsupported_browser_warning||window.addEventListener("DOMContentLoaded",async function(){const{testSupportedBrowser:e}=await Promise.all([t.e(4208),t.e(7883)]).then(t.bind(t,77883));e()})}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var t=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=o,e=[],a.O=(r,t,o,n)=>{if(!t){var i=1/0;for(s=0;s<e.length;s++){for(var[t,o,n]=e[s],l=!0,d=0;d<t.length;d++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[d]))?t.splice(d--,1):(l=!1,n<i&&(i=n));if(l){e.splice(s--,1);var c=o();void 0!==c&&(r=c)}}return r}n=n||0;for(var s=e.length;s>0&&e[s-1][2]>n;s--)e[s]=e[s-1];e[s]=[t,o,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce((r,t)=>(a.f[t](e,r),r),[])),a.u=e=>e+"-"+e+".js?v=3d4ae877fbe2b14cce7b",a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="nextcloud-ui-legacy:",a.l=(e,o,n,i)=>{if(r[e])r[e].push(o);else{var l,d;if(void 0!==n)for(var c=document.getElementsByTagName("script"),s=0;s<c.length;s++){var u=c[s];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==t+n){l=u;break}}l||(d=!0,(l=document.createElement("script")).charset="utf-8",a.nc&&l.setAttribute("nonce",a.nc),l.setAttribute("data-webpack",t+n),l.src=e),r[e]=[o];var p=(t,o)=>{l.onerror=l.onload=null,clearTimeout(f);var n=r[e];if(delete r[e],l.parentNode&&l.parentNode.removeChild(l),n&&n.forEach(e=>e(o)),t)return t(o)},f=setTimeout(p.bind(null,void 0,{type:"timeout",target:l}),12e4);l.onerror=p.bind(null,l.onerror),l.onload=p.bind(null,l.onload),d&&document.head.appendChild(l)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.j=3604,(()=>{var e;globalThis.importScripts&&(e=globalThis.location+"");var r=globalThis.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&(!e||!/^http(s?):/.test(e));)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={3604:0};a.f.j=(r,t)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else{var n=new Promise((t,n)=>o=e[r]=[t,n]);t.push(o[2]=n);var i=a.p+a.u(r),l=new Error;a.l(i,t=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var n=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;l.message="Loading chunk "+r+" failed.\n("+n+": "+i+")",l.name="ChunkLoadError",l.type=n,l.request=i,o[1](l)}},"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var o,n,[i,l,d]=t,c=0;if(i.some(r=>0!==e[r])){for(o in l)a.o(l,o)&&(a.m[o]=l[o]);if(d)var s=d(a)}for(r&&r(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(s)},t=globalThis.webpackChunknextcloud_ui_legacy=globalThis.webpackChunknextcloud_ui_legacy||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0;var i=a.O(void 0,[4208],()=>a(47210));i=a.O(i)})();
//# sourceMappingURL=core-unsupported-browser-redirect.js.map?v=d045d81021cc2e1e9948

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long