MOBILE-3780 core: Don't store offline if 4xx or 5xx http error
parent
be0ce93a0f
commit
9ded4b7c5b
|
@ -36,6 +36,7 @@ import {
|
||||||
import { AddonModAssignHelper } from '../../services/assign-helper';
|
import { AddonModAssignHelper } from '../../services/assign-helper';
|
||||||
import { AddonModAssignOffline } from '../../services/assign-offline';
|
import { AddonModAssignOffline } from '../../services/assign-offline';
|
||||||
import { AddonModAssignSync } from '../../services/assign-sync';
|
import { AddonModAssignSync } from '../../services/assign-sync';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that allows adding or editing an assigment submission.
|
* Page that allows adding or editing an assigment submission.
|
||||||
|
@ -255,7 +256,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave {
|
||||||
this.hasOffline,
|
this.hasOffline,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.allowOffline && !this.saveOffline) {
|
if (this.allowOffline && !this.saveOffline && !CoreUtils.isWebServiceError(error)) {
|
||||||
// Cannot submit in online, prepare for offline usage.
|
// Cannot submit in online, prepare for offline usage.
|
||||||
this.saveOffline = true;
|
this.saveOffline = true;
|
||||||
|
|
||||||
|
|
|
@ -266,9 +266,10 @@ export class AddonModDataEditPage implements OnInit {
|
||||||
this.offline,
|
this.offline,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.offline) {
|
if (this.offline || CoreUtils.isWebServiceError(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cannot submit in online, prepare for offline usage.
|
// Cannot submit in online, prepare for offline usage.
|
||||||
this.offline = true;
|
this.offline = true;
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Cannot upload them in online, save them in offline.
|
// Cannot upload them in online, save them in offline.
|
||||||
if (!this.forum.id || isEditOnline) {
|
if (!this.forum.id || isEditOnline || CoreUtils.isWebServiceError(error)) {
|
||||||
// Cannot store them in offline. Reject.
|
// Cannot store them in offline. Reject.
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,10 @@ export class AddonModForumHelperProvider {
|
||||||
try {
|
try {
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot upload them in online, save them in offline.
|
// Cannot upload them in online, save them in offline.
|
||||||
saveOffline = true;
|
saveOffline = true;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
|
@ -392,7 +393,11 @@ export class AddonModGlossaryEditPage implements OnInit, OnDestroy, CanLeave {
|
||||||
saveOffline: false,
|
saveOffline: false,
|
||||||
attachmentsResult,
|
attachmentsResult,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch (error) {
|
||||||
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot upload them in online, save them in offline.
|
// Cannot upload them in online, save them in offline.
|
||||||
const attachmentsResult = await AddonModGlossaryHelper.storeFiles(
|
const attachmentsResult = await AddonModGlossaryHelper.storeFiles(
|
||||||
this.glossary.id,
|
this.glossary.id,
|
||||||
|
|
|
@ -304,7 +304,11 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
||||||
files,
|
files,
|
||||||
saveOffline,
|
saveOffline,
|
||||||
);
|
);
|
||||||
} catch {
|
} catch (error) {
|
||||||
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot upload them in online, save them in offline.
|
// Cannot upload them in online, save them in offline.
|
||||||
saveOffline = true;
|
saveOffline = true;
|
||||||
allowOffline = true;
|
allowOffline = true;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { CoreSites } from '@services/sites';
|
||||||
import { CoreSync } from '@services/sync';
|
import { CoreSync } from '@services/sync';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
|
@ -349,7 +350,11 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy, Ca
|
||||||
inputData.attachmentfiles,
|
inputData.attachmentfiles,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
} catch {
|
} catch (error) {
|
||||||
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot upload them in online, save them in offline.
|
// Cannot upload them in online, save them in offline.
|
||||||
saveOffline = true;
|
saveOffline = true;
|
||||||
allowOffline = true;
|
allowOffline = true;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreCaptureError } from './captureerror';
|
||||||
import { CoreNetworkError } from './network-error';
|
import { CoreNetworkError } from './network-error';
|
||||||
import { CoreSiteError } from './siteerror';
|
import { CoreSiteError } from './siteerror';
|
||||||
import { CoreErrorWithTitle } from './errorwithtitle';
|
import { CoreErrorWithTitle } from './errorwithtitle';
|
||||||
|
import { CoreHttpError } from './httperror';
|
||||||
|
|
||||||
export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
|
export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
|
||||||
CoreAjaxError,
|
CoreAjaxError,
|
||||||
|
@ -36,4 +37,5 @@ export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
|
||||||
CoreSiteError,
|
CoreSiteError,
|
||||||
CoreWSError,
|
CoreWSError,
|
||||||
CoreErrorWithTitle,
|
CoreErrorWithTitle,
|
||||||
|
CoreHttpError,
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreError } from '@classes/errors/error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP error.
|
||||||
|
*/
|
||||||
|
export class CoreHttpError extends CoreError {
|
||||||
|
|
||||||
|
status: number; // HTTP status. 0 if cannot connect or similar errors.
|
||||||
|
|
||||||
|
constructor(message: string, status?: number) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.status = status ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -858,12 +858,17 @@ export class CoreUtilsProvider {
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
isWebServiceError(error: any): boolean {
|
isWebServiceError(error: any): boolean {
|
||||||
return error && (error.warningcode !== undefined || (error.errorcode !== undefined &&
|
return error && (
|
||||||
error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' &&
|
error.warningcode !== undefined ||
|
||||||
|
(
|
||||||
|
error.errorcode !== undefined && error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' &&
|
||||||
error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' &&
|
error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' &&
|
||||||
error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' &&
|
error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' &&
|
||||||
error.errorcode != 'wsaccessusersuspended' && error.errorcode != 'wsaccessuserdeleted' &&
|
error.errorcode != 'wsaccessusersuspended' && error.errorcode != 'wsaccessuserdeleted' &&
|
||||||
!this.isExpiredTokenError(error)));
|
!this.isExpiredTokenError(error)
|
||||||
|
) ||
|
||||||
|
error.status && error.status >= 400 // CoreHttpError, assume status 400 and above are like WebService errors.
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { CoreNativeToAngularHttpResponse } from '@classes/native-to-angular-http
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreFile, CoreFileFormat } from '@services/file';
|
import { CoreFile, CoreFileFormat } from '@services/file';
|
||||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextErrorObject, CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
|
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
|
@ -38,6 +38,7 @@ import { CoreAjaxError } from '@classes/errors/ajaxerror';
|
||||||
import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
|
import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
|
||||||
import { CoreNetworkError } from '@classes/errors/network-error';
|
import { CoreNetworkError } from '@classes/errors/network-error';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite } from '@classes/site';
|
||||||
|
import { CoreHttpError } from '@classes/errors/httperror';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service allows performing WS calls and download/upload files.
|
* This service allows performing WS calls and download/upload files.
|
||||||
|
@ -693,6 +694,8 @@ export class CoreWSProvider {
|
||||||
return retryPromise;
|
return retryPromise;
|
||||||
} else if (error.status === -2) {
|
} else if (error.status === -2) {
|
||||||
throw new CoreError(this.getCertificateErrorMessage(error.error));
|
throw new CoreError(this.getCertificateErrorMessage(error.error));
|
||||||
|
} else if (error.status > 0) {
|
||||||
|
throw this.createHttpError(error, error.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.serverconnection'));
|
throw new CoreError(Translate.instant('core.serverconnection'));
|
||||||
|
@ -892,10 +895,7 @@ export class CoreWSProvider {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Error while uploading file', filePath, error);
|
this.logger.error('Error while uploading file', filePath, error);
|
||||||
|
|
||||||
throw new CoreError(CoreTextUtils.buildSeveralParagraphsMessage([
|
throw this.createHttpError(error, error.http_status ?? 0);
|
||||||
Translate.instant('core.cannotconnecttrouble'),
|
|
||||||
CoreTextUtils.getHTMLBodyContent(CoreTextUtils.getErrorMessageFromError(error) || ''),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
@ -937,6 +937,22 @@ export class CoreWSProvider {
|
||||||
return data[0];
|
return data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a CoreHttpError based on a certain error.
|
||||||
|
*
|
||||||
|
* @param error Original error.
|
||||||
|
* @param status Status code (if any).
|
||||||
|
* @return CoreHttpError.
|
||||||
|
*/
|
||||||
|
protected createHttpError(error: CoreTextErrorObject, status: number): CoreHttpError {
|
||||||
|
const message = CoreTextUtils.buildSeveralParagraphsMessage([
|
||||||
|
Translate.instant('core.cannotconnecttrouble'),
|
||||||
|
CoreTextUtils.getHTMLBodyContent(CoreTextUtils.getErrorMessageFromError(error) || ''),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new CoreHttpError(message, status);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform an HTTP request requesting for a text response.
|
* Perform an HTTP request requesting for a text response.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue