MOBILE-4059 core: Refactor site errors hierarchy

main
Noel De Martin 2022-10-06 14:05:46 +02:00
parent 734f1c6323
commit 23341a7436
5 changed files with 65 additions and 29 deletions

View File

@ -23,6 +23,7 @@ import { CoreAjaxWSError } from './ajaxwserror';
import { CoreCaptureError } from './captureerror';
import { CoreNetworkError } from './network-error';
import { CoreSiteError } from './siteerror';
import { CoreLoginError } from './loginerror';
import { CoreErrorWithOptions } from './errorwithtitle';
import { CoreHttpError } from './httperror';
@ -35,6 +36,7 @@ export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
CoreNetworkError,
CoreSilentError,
CoreSiteError,
CoreLoginError,
CoreWSError,
CoreErrorWithOptions,
CoreHttpError,

View File

@ -0,0 +1,37 @@
// (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 { CoreSiteError, CoreSiteErrorOptions } from '@classes/errors/siteerror';
/**
* Error returned when performing operations during login.
*/
export class CoreLoginError extends CoreSiteError {
critical?: boolean;
loggedOut?: boolean;
constructor(options: CoreLoginErrorOptions) {
super(options);
this.critical = options.critical;
this.loggedOut = options.loggedOut;
}
}
export type CoreLoginErrorOptions = CoreSiteErrorOptions & {
critical?: boolean; // Whether the error is important enough to abort the operation.
loggedOut?: boolean; // Whether site has been marked as logged out.
};

View File

@ -17,14 +17,12 @@ import { CoreSitePublicConfigResponse } from '@classes/site';
import { CoreUserSupport } from '@features/user/services/support';
/**
* Error returned when performing operations regarding a site (check if it exists, authenticate user, etc.).
* Error returned when performing operations regarding a site.
*/
export class CoreSiteError extends CoreError {
errorcode?: string;
errorDetails?: string;
critical?: boolean;
loggedOut?: boolean;
contactSupport?: boolean;
siteConfig?: CoreSitePublicConfigResponse;
@ -33,8 +31,6 @@ export class CoreSiteError extends CoreError {
this.errorcode = options.errorcode;
this.errorDetails = options.errorDetails;
this.critical = options.critical;
this.loggedOut = options.loggedOut;
this.contactSupport = options.contactSupport;
this.siteConfig = options.siteConfig;
}
@ -86,11 +82,9 @@ function getErrorMessage(options: CoreSiteErrorOptions): string {
export type CoreSiteErrorOptions = {
message: string;
fallbackMessage?: string; // Message to use if contacting support was intended but isn't possible.
errorcode?: string;
errorDetails?: string;
critical?: boolean; // Whether the error is important enough to abort the operation.
loggedOut?: boolean; // Whether site has been marked as logged out.
contactSupport?: boolean;
fallbackMessage?: string; // Message to use when contacting support is not possible but warranted.
errorcode?: string; // Technical error code useful for technical assistance.
errorDetails?: string; // Technical error details useful for technical assistance.
contactSupport?: boolean; // Whether this error warrants contacting site support or not.
siteConfig?: CoreSitePublicConfigResponse;
};

View File

@ -14,7 +14,7 @@
import { CoreSharedModule } from '@/core/shared.module';
import { findElement, mockSingleton, renderPageComponent, requireElement } from '@/testing/utils';
import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreLoginError } from '@classes/errors/loginerror';
import { CoreLoginComponentsModule } from '@features/login/components/components.module';
import { CoreLoginCredentialsPage } from '@features/login/pages/credentials/credentials';
import { CoreSites } from '@services/sites';
@ -42,7 +42,7 @@ describe('Credentials page', () => {
// Arrange.
mockSingleton(CoreSites, {
getUserToken: () => {
throw new CoreSiteError({
throw new CoreLoginError({
message: '',
errorcode: 'invalidlogin',
});

View File

@ -34,7 +34,7 @@ import {
} from '@classes/site';
import { SQLiteDB, SQLiteDBRecordValues, SQLiteDBTableSchema } from '@classes/sqlitedb';
import { CoreError } from '@classes/errors/error';
import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreLoginError } from '@classes/errors/loginerror';
import { makeSingleton, Translate, Http } from '@singletons';
import { CoreLogger } from '@singletons/logger';
import {
@ -313,7 +313,7 @@ export class CoreSitesProvider {
message += config.maintenancemessage;
}
throw new CoreSiteError({
throw new CoreLoginError({
message,
critical: true,
});
@ -336,8 +336,8 @@ export class CoreSitesProvider {
errorcode: string,
errorDetails: string,
siteConfig: CoreSitePublicConfigResponse,
): CoreSiteError {
return new CoreSiteError({
): CoreLoginError {
return new CoreLoginError({
errorcode,
errorDetails,
siteConfig,
@ -349,16 +349,19 @@ export class CoreSitesProvider {
}
/**
* Treat an error returned by getPublicConfig in checkSiteWithProtocol. Converts the error to a CoreSiteError.
* Treat an error returned by getPublicConfig in checkSiteWithProtocol. Converts the error to a CoreLoginError.
*
* @param siteUrl Site URL.
* @param error Error returned.
* @return Promise resolved with the treated error.
*/
protected async treatGetPublicConfigError(siteUrl: string, error: CoreAjaxError | CoreAjaxWSError): Promise<CoreSiteError> {
if (!('errorcode' in error)) {
protected async treatGetPublicConfigError(
siteUrl: string,
error: CoreError | CoreAjaxError | CoreAjaxWSError,
): Promise<CoreLoginError> {
if (error instanceof CoreAjaxError || !('errorcode' in error)) {
// The WS didn't return data, probably cannot connect.
return new CoreSiteError({
return new CoreLoginError({
message: error.message || '',
critical: false, // Allow fallback to http if siteUrl uses https.
});
@ -385,7 +388,7 @@ export class CoreSitesProvider {
critical = false; // Keep checking fallback URLs.
}
return new CoreSiteError({
return new CoreLoginError({
message: error.message,
errorcode: error.errorcode,
critical,
@ -410,27 +413,27 @@ export class CoreSitesProvider {
.toPromise();
} catch (error) {
// Default error messages are kinda bad, return our own message.
throw new CoreSiteError({
throw new CoreLoginError({
message: Translate.instant('core.cannotconnecttrouble'),
});
}
if (data === null) {
// Cannot connect.
throw new CoreSiteError({
throw new CoreLoginError({
message: Translate.instant('core.cannotconnect', { $a: CoreSite.MINIMUM_MOODLE_VERSION }),
});
}
if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) {
throw new CoreSiteError({
throw new CoreLoginError({
errorcode: data.errorcode,
message: data.error ?? '',
});
}
if (data.error && data.error == 'Web services must be enabled in Advanced features.') {
throw new CoreSiteError({
throw new CoreLoginError({
errorcode: 'enablewsdescription',
message: data.error,
});
@ -492,13 +495,13 @@ export class CoreSitesProvider {
const redirect = await CoreUtils.checkRedirect(loginUrl);
if (redirect) {
throw new CoreSiteError({
throw new CoreLoginError({
message: Translate.instant('core.login.sitehasredirect'),
});
}
}
throw new CoreSiteError({
throw new CoreLoginError({
message: data.error,
errorcode: data.errorcode,
});
@ -641,7 +644,7 @@ export class CoreSitesProvider {
await this.setSiteLoggedOut(siteId);
}
throw new CoreSiteError({
throw new CoreLoginError({
message: Translate.instant(errorKey, translateParams),
errorcode: errorCode,
loggedOut: true,