diff --git a/src/core/classes/site.ts b/src/core/classes/site.ts index 0c8ef1484..6a69f8986 100644 --- a/src/core/classes/site.ts +++ b/src/core/classes/site.ts @@ -1697,6 +1697,10 @@ export class CoreSite { */ async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise { if (!this.db) { + if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_CACHE) { + throw new CoreError('Cache not available to read public config'); + } + return this.requestPublicConfig(); } diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index 6e0ea348b..57c171c47 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -34,7 +34,7 @@ import { } from '@classes/site'; import { SQLiteDB, SQLiteDBRecordValues, SQLiteDBTableSchema } from '@classes/sqlitedb'; import { CoreError } from '@classes/errors/error'; -import { CoreLoginError } from '@classes/errors/loginerror'; +import { CoreLoginError, CoreLoginErrorOptions } from '@classes/errors/loginerror'; import { makeSingleton, Translate, Http } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { @@ -296,17 +296,19 @@ export class CoreSitesProvider { // Check that the user can authenticate. if (!config.enablewebservices) { - throw this.createCannotConnectError( - 'webservicesnotenabled', - Translate.instant('core.login.webservicesnotenabled'), - config, - ); + throw this.createCannotConnectError({ + errorcode: 'webservicesnotenabled', + errorDetails: Translate.instant('core.login.webservicesnotenabled'), + siteConfig: config, + critical: true, + }); } else if (!config.enablemobilewebservice) { - throw this.createCannotConnectError( - 'mobileservicesnotenabled', - Translate.instant('core.login.mobileservicesnotenabled'), - config, - ); + throw this.createCannotConnectError({ + errorcode: 'mobileservicesnotenabled', + errorDetails: Translate.instant('core.login.mobileservicesnotenabled'), + siteConfig: config, + critical: true, + }); } else if (config.maintenanceenabled) { let message = Translate.instant('core.sitemaintenance'); if (config.maintenancemessage) { @@ -327,23 +329,14 @@ export class CoreSitesProvider { /** * Create an error to be thrown when it isn't possible to connect to a site. * - * @param errorcode Error code. - * @param errorDetails Error details. - * @param siteConfig Site config. + * @param options Error options. * @return Cannot connect error. */ - protected createCannotConnectError( - errorcode: string, - errorDetails: string, - siteConfig: CoreSitePublicConfigResponse, - ): CoreLoginError { + protected createCannotConnectError(options: Partial = {}): CoreLoginError { return new CoreLoginError({ - errorcode, - errorDetails, - siteConfig, + ...options, message: Translate.instant('core.cannotconnecttrouble'), fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'), - critical: true, contactSupport: true, }); } @@ -433,9 +426,12 @@ export class CoreSitesProvider { } if (data.error && data.error == 'Web services must be enabled in Advanced features.') { - throw new CoreLoginError({ + const siteConfig = await CoreUtils.ignoreErrors(this.getPublicSiteConfigByUrl(siteUrl)); + + throw this.createCannotConnectError({ errorcode: 'enablewsdescription', - message: data.error, + errorDetails: data.error, + siteConfig, }); } @@ -1110,6 +1106,18 @@ export class CoreSitesProvider { return this.addSiteFromSiteListEntry(data); } + /** + * Gets the public type config for a site with the given url. + * + * @param siteUrl The site URL. + * @return Promise resolved with public config or null. + */ + async getPublicSiteConfigByUrl(siteUrl: string): Promise { + const site = await this.getSiteByUrl(siteUrl); + + return site.getPublicConfig({ readingStrategy: CoreSitesReadingStrategy.ONLY_CACHE }); + } + /** * Create a site from an entry of the sites list DB. The new site is added to the list of "cached" sites: this.sites. * diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 10561519e..da36d7068 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -54,6 +54,9 @@ import { Subscription } from 'rxjs'; import { CoreComponentsRegistry } from '@singletons/components-registry'; import { CoreDom } from '@singletons/dom'; import { CoreNetwork } from '@services/network'; +import { CoreSiteError } from '@classes/errors/siteerror'; +import { CoreUserSupport } from '@features/user/services/support'; +import { CoreErrorInfoComponent } from '@components/error-info/error-info'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -1356,11 +1359,40 @@ export class CoreDomUtilsProvider { if (typeof error !== 'string' && 'buttons' in error && typeof error.buttons !== 'undefined') { alertOptions.buttons = error.buttons; + } else if (error instanceof CoreSiteError) { + alertOptions.buttons = []; + + if (error.errorDetails) { + alertOptions.message += '
'; + } + + if (error.canContactSupport()) { + alertOptions.buttons.push({ + text: Translate.instant('core.contactsupport'), + handler: () => CoreUserSupport.contact({ + supportPageUrl: error.getSupportPageUrl(), + subject: alertOptions.header, + message: `${error.errorcode}\n\n${error.errorDetails}`, + }), + }); + } + + alertOptions.buttons.push(Translate.instant('core.ok')); } else { alertOptions.buttons = [Translate.instant('core.ok')]; } - return this.showAlertWithOptions(alertOptions, autocloseTime); + const alertElement = await this.showAlertWithOptions(alertOptions, autocloseTime); + + if (error instanceof CoreSiteError && error.errorDetails) { + const containerElement = alertElement.querySelector('.core-error-info-container'); + + if (containerElement) { + containerElement.innerHTML = CoreErrorInfoComponent.render(error.errorDetails, error.errorcode); + } + } + + return alertElement; } /**