forked from EVOgeek/Vmeda.Online
MOBILE-4059 core: Improve errors mentioning admins
parent
dca3f76296
commit
dabd4e8046
|
@ -1919,8 +1919,6 @@
|
||||||
"core.login.connecttomoodle": "local_moodlemobileapp",
|
"core.login.connecttomoodle": "local_moodlemobileapp",
|
||||||
"core.login.connecttomoodleapp": "local_moodlemobileapp",
|
"core.login.connecttomoodleapp": "local_moodlemobileapp",
|
||||||
"core.login.connecttoworkplaceapp": "local_moodlemobileapp",
|
"core.login.connecttoworkplaceapp": "local_moodlemobileapp",
|
||||||
"core.login.contactyouradministrator": "local_moodlemobileapp",
|
|
||||||
"core.login.contactyouradministratorissue": "local_moodlemobileapp",
|
|
||||||
"core.login.createaccount": "moodle",
|
"core.login.createaccount": "moodle",
|
||||||
"core.login.createuserandpass": "moodle",
|
"core.login.createuserandpass": "moodle",
|
||||||
"core.login.credentialsdescription": "local_moodlemobileapp",
|
"core.login.credentialsdescription": "local_moodlemobileapp",
|
||||||
|
@ -1955,7 +1953,6 @@
|
||||||
"core.login.forcepasswordchangenotice": "moodle",
|
"core.login.forcepasswordchangenotice": "moodle",
|
||||||
"core.login.forgotten": "moodle",
|
"core.login.forgotten": "moodle",
|
||||||
"core.login.help": "moodle",
|
"core.login.help": "moodle",
|
||||||
"core.login.helpmelogin": "local_moodlemobileapp",
|
|
||||||
"core.login.instructions": "auth",
|
"core.login.instructions": "auth",
|
||||||
"core.login.invalidaccount": "local_moodlemobileapp",
|
"core.login.invalidaccount": "local_moodlemobileapp",
|
||||||
"core.login.invaliddate": "calendar/errorinvaliddate",
|
"core.login.invaliddate": "calendar/errorinvaliddate",
|
||||||
|
@ -2398,7 +2395,6 @@
|
||||||
"core.weeks": "moodle",
|
"core.weeks": "moodle",
|
||||||
"core.whatisyourage": "moodle",
|
"core.whatisyourage": "moodle",
|
||||||
"core.wheredoyoulive": "moodle",
|
"core.wheredoyoulive": "moodle",
|
||||||
"core.whoissiteadmin": "local_moodlemobileapp",
|
|
||||||
"core.whyisthishappening": "local_moodlemobileapp",
|
"core.whyisthishappening": "local_moodlemobileapp",
|
||||||
"core.whyisthisrequired": "moodle",
|
"core.whyisthisrequired": "moodle",
|
||||||
"core.wsfunctionnotavailable": "local_moodlemobileapp",
|
"core.wsfunctionnotavailable": "local_moodlemobileapp",
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"errordownloadscorm": "Error downloading SCORM: \"{{name}}\".",
|
"errordownloadscorm": "Error downloading SCORM: \"{{name}}\".",
|
||||||
"errorgetscorm": "Error getting SCORM data.",
|
"errorgetscorm": "Error getting SCORM data.",
|
||||||
"errorinvalidversion": "Sorry, the application only supports SCORM 1.2.",
|
"errorinvalidversion": "Sorry, the application only supports SCORM 1.2.",
|
||||||
"errornotdownloadable": "The download of SCORM packages is disabled. Please contact your site administrator.",
|
"errornotdownloadable": "This institution has disabled the download of SCORM packages.",
|
||||||
"errornovalidsco": "This SCORM package doesn't have a visible SCO to load.",
|
"errornovalidsco": "This SCORM package doesn't have a visible SCO to load.",
|
||||||
"errorpackagefile": "Sorry, the application only supports ZIP packages.",
|
"errorpackagefile": "Sorry, the application only supports ZIP packages.",
|
||||||
"errorsyncscorm": "An error occurred while synchronising. Please try again.",
|
"errorsyncscorm": "An error occurred while synchronising. Please try again.",
|
||||||
|
@ -49,4 +49,4 @@
|
||||||
"toc": "TOC",
|
"toc": "TOC",
|
||||||
"warningofflinedatadeleted": "Some offline data from attempt {{number}} has been discarded because it couldn't be counted as a new attempt.",
|
"warningofflinedatadeleted": "Some offline data from attempt {{number}} has been discarded because it couldn't be counted as a new attempt.",
|
||||||
"warningsynconlineincomplete": "Some attempts couldn't be synchronised with the site because the last online attempt is not yet finished. Please finish the online attempt first."
|
"warningsynconlineincomplete": "Some attempts couldn't be synchronised with the site because the last online attempt is not yet finished. Please finish the online attempt first."
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,14 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreSiteError } from '@classes/errors/siteerror';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error returned by WS.
|
* Error returned by WS.
|
||||||
*/
|
*/
|
||||||
export class CoreAjaxWSError extends CoreError {
|
export class CoreAjaxWSError extends CoreSiteError {
|
||||||
|
|
||||||
exception?: string; // Name of the Moodle exception.
|
exception?: string; // Name of the Moodle exception.
|
||||||
errorcode?: string;
|
|
||||||
warningcode?: string;
|
warningcode?: string;
|
||||||
link?: string; // Link to the site.
|
link?: string; // Link to the site.
|
||||||
moreinfourl?: string; // Link to a page with more info.
|
moreinfourl?: string; // Link to a page with more info.
|
||||||
|
@ -30,10 +29,12 @@ export class CoreAjaxWSError extends CoreError {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
constructor(error: any, available?: number) {
|
constructor(error: any, available?: number) {
|
||||||
super(error.message || error.error);
|
super({
|
||||||
|
message: error.message || error.error,
|
||||||
|
errorcode: error.errorcode,
|
||||||
|
});
|
||||||
|
|
||||||
this.exception = error.exception;
|
this.exception = error.exception;
|
||||||
this.errorcode = error.errorcode;
|
|
||||||
this.warningcode = error.warningcode;
|
this.warningcode = error.warningcode;
|
||||||
this.link = error.link;
|
this.link = error.link;
|
||||||
this.moreinfourl = error.moreinfourl;
|
this.moreinfourl = error.moreinfourl;
|
||||||
|
|
|
@ -61,6 +61,7 @@ import { Observable, ObservableInput, ObservedValueOf, OperatorFunction, Subject
|
||||||
import { finalize, map, mergeMap } from 'rxjs/operators';
|
import { finalize, map, mergeMap } from 'rxjs/operators';
|
||||||
import { firstValueFrom } from '../utils/rxjs';
|
import { firstValueFrom } from '../utils/rxjs';
|
||||||
import { CoreUserSupport } from '@features/user/services/support';
|
import { CoreUserSupport } from '@features/user/services/support';
|
||||||
|
import { CoreSiteError } from '@classes/errors/siteerror';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QR Code type enumeration.
|
* QR Code type enumeration.
|
||||||
|
@ -1157,7 +1158,18 @@ export class CoreSite {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data || !data.responses) {
|
if (!data || !data.responses) {
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
const siteConfig = await CoreUtils.ignoreErrors(
|
||||||
|
this.getPublicConfig({ readingStrategy: CoreSitesReadingStrategy.ONLY_CACHE }),
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new CoreSiteError({
|
||||||
|
siteConfig,
|
||||||
|
contactSupport: true,
|
||||||
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method: 'tool_mobile_call_external_functions' }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
requests.forEach((request, i) => {
|
requests.forEach((request, i) => {
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p>{{ 'core.login.faqcannotconnectanswer' | translate }} {{ 'core.whoissiteadmin' | translate }}</p>
|
<p>{{ 'core.login.faqcannotconnectanswer' | translate }}</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
|
|
|
@ -14,13 +14,11 @@
|
||||||
"connecttomoodle": "Connect to Moodle",
|
"connecttomoodle": "Connect to Moodle",
|
||||||
"connecttomoodleapp": "You are trying to connect to a regular Moodle site. Please download the official Moodle app to access this site.",
|
"connecttomoodleapp": "You are trying to connect to a regular Moodle site. Please download the official Moodle app to access this site.",
|
||||||
"connecttoworkplaceapp": "You are trying to connect to a Moodle Workplace site. Please download the Moodle Workplace app to access this site.",
|
"connecttoworkplaceapp": "You are trying to connect to a Moodle Workplace site. Please download the Moodle Workplace app to access this site.",
|
||||||
"contactyouradministrator": "Contact your site administrator for further help.",
|
|
||||||
"contactyouradministratorissue": "Please ask your site administrator to check the following issue: {{$a}}",
|
|
||||||
"createaccount": "Create my new account",
|
"createaccount": "Create my new account",
|
||||||
"createuserandpass": "Choose your username and password",
|
"createuserandpass": "Choose your username and password",
|
||||||
"credentialsdescription": "Please provide your username and password to log in.",
|
"credentialsdescription": "Please provide your username and password to log in.",
|
||||||
"emailconfirmsent": "<p>An email should have been sent to your address at <b>{{$a}}</b></p>\n <p>It contains easy instructions to complete your registration.</p>\n <p>If you continue to have difficulty, contact the site administrator.</p>",
|
"emailconfirmsent": "<p>An email should have been sent to your address at <b>{{$a}}</b></p><p>It contains easy instructions to complete your registration.</p>",
|
||||||
"emailconfirmsentnoemail": "<p>An email should have been sent to your address.</p><p>It contains easy instructions to complete your registration.</p><p>If you continue to have difficulty, contact the site administrator.</p>",
|
"emailconfirmsentnoemail": "<p>An email should have been sent to your address.</p><p>It contains easy instructions to complete your registration.</p>",
|
||||||
"emailconfirmsentsuccess": "Confirmation email sent successfully",
|
"emailconfirmsentsuccess": "Confirmation email sent successfully",
|
||||||
"emailnotmatch": "Emails do not match",
|
"emailnotmatch": "Emails do not match",
|
||||||
"erroraccesscontrolalloworigin": "The cross-origin call you're trying to perform has been rejected. Please check https://docs.moodle.org/dev/Moodle_Mobile_development_using_Chrome_or_Chromium",
|
"erroraccesscontrolalloworigin": "The cross-origin call you're trying to perform has been rejected. Please check https://docs.moodle.org/dev/Moodle_Mobile_development_using_Chrome_or_Chromium",
|
||||||
|
@ -32,7 +30,7 @@
|
||||||
"exceededloginattemptssupportsubject": "I can't log in",
|
"exceededloginattemptssupportsubject": "I can't log in",
|
||||||
"exceededpasswordresetattempts": "It seems you are having trouble accessing your account. You can contact your administrator or try again later.",
|
"exceededpasswordresetattempts": "It seems you are having trouble accessing your account. You can contact your administrator or try again later.",
|
||||||
"exceededpasswordresetattemptssupportsubject": "I can't reset my password",
|
"exceededpasswordresetattemptssupportsubject": "I can't reset my password",
|
||||||
"faqcannotconnectanswer": "Please, contact your site administrator.",
|
"faqcannotconnectanswer": "Please, contact your institution.",
|
||||||
"faqcannotconnectquestion": "I typed my site address correctly but I still can't connect.",
|
"faqcannotconnectquestion": "I typed my site address correctly but I still can't connect.",
|
||||||
"faqcannotfindmysiteanswer": "Have you typed the name correctly? It's also possible that your site is not included in our public sites directory. If you still can't find it, please enter your site address instead.",
|
"faqcannotfindmysiteanswer": "Have you typed the name correctly? It's also possible that your site is not included in our public sites directory. If you still can't find it, please enter your site address instead.",
|
||||||
"faqcannotfindmysitequestion": "I can't find my site.",
|
"faqcannotfindmysitequestion": "I can't find my site.",
|
||||||
|
@ -50,12 +48,11 @@
|
||||||
"forcepasswordchangenotice": "You must change your password to proceed.",
|
"forcepasswordchangenotice": "You must change your password to proceed.",
|
||||||
"forgotten": "Forgotten your username or password?",
|
"forgotten": "Forgotten your username or password?",
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"helpmelogin": "<p>There are many thousands of Moodle sites around the world. This app can only connect to Moodle sites that have specifically enabled Mobile app access.</p><p>If you can't connect to your Moodle site then you need to contact your site administrator and ask them to read <a href=\"http://docs.moodle.org/en/Mobile_app\" target=\"_blank\">http://docs.moodle.org/en/Mobile_app</a></p><p>To test the app in a Moodle demo site type <i>teacher</i> or <i>student</i> in the <i>Site address</i> field and click the <b>Connect button</b>.</p>",
|
|
||||||
"instructions": "Instructions",
|
"instructions": "Instructions",
|
||||||
"invalidaccount": "Please check your login details or ask your site administrator to check the site configuration.",
|
"invalidaccount": "Please check your login details and try again.",
|
||||||
"invaliddate": "Invalid date",
|
"invaliddate": "Invalid date",
|
||||||
"invalidemail": "Invalid email address",
|
"invalidemail": "Invalid email address",
|
||||||
"invalidmoodleversion": "<p>Invalid Moodle site version. The Moodle app only supports Moodle systems {{$a}} onwards.</p>\n<p>You can contact your site administrators and ask them to update their Moodle system.</p>\n<p>\"Site Administrators\" are the people who manages the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.</p>",
|
"invalidmoodleversion": "Invalid Moodle site version. The Moodle app only supports Moodle systems {{$a}} onwards.",
|
||||||
"invalidsite": "The site URL is invalid.",
|
"invalidsite": "The site URL is invalid.",
|
||||||
"invalidtime": "Invalid time",
|
"invalidtime": "Invalid time",
|
||||||
"invalidurl": "Invalid URL specified",
|
"invalidurl": "Invalid URL specified",
|
||||||
|
@ -69,7 +66,7 @@
|
||||||
"missingemail": "Missing email address",
|
"missingemail": "Missing email address",
|
||||||
"missingfirstname": "Missing given name",
|
"missingfirstname": "Missing given name",
|
||||||
"missinglastname": "Missing surname",
|
"missinglastname": "Missing surname",
|
||||||
"mobileservicesnotenabled": "Mobile access is not enabled on your site. Please contact your site administrator if you think it should be enabled.",
|
"mobileservicesnotenabled": "Mobile services are not enabled on the site.",
|
||||||
"mustconfirm": "You need to confirm your account",
|
"mustconfirm": "You need to confirm your account",
|
||||||
"newaccount": "New account",
|
"newaccount": "New account",
|
||||||
"notloggedin": "You need to be logged in.",
|
"notloggedin": "You need to be logged in.",
|
||||||
|
@ -127,7 +124,7 @@
|
||||||
"usernamerequired": "Username required",
|
"usernamerequired": "Username required",
|
||||||
"usernotaddederror": "User not added - error",
|
"usernotaddederror": "User not added - error",
|
||||||
"visitchangepassword": "Do you want to visit the site to change the password?",
|
"visitchangepassword": "Do you want to visit the site to change the password?",
|
||||||
"webservicesnotenabled": "Your host site may not have enabled Web services. Please contact your administrator for help.",
|
"webservicesnotenabled": "Web services are not enabled on the site.",
|
||||||
"youcanstillconnectwithcredentials": "You can still connect to the site by entering your username and password.",
|
"youcanstillconnectwithcredentials": "You can still connect to the site by entering your username and password.",
|
||||||
"yourenteredsite": "Connect to your site"
|
"yourenteredsite": "Connect to your site"
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,26 @@ describe('Credentials page', () => {
|
||||||
// Arrange.
|
// Arrange.
|
||||||
const siteUrl = 'https://campus.example.edu';
|
const siteUrl = 'https://campus.example.edu';
|
||||||
|
|
||||||
|
mockSingleton(CoreSites, {
|
||||||
|
getPublicSiteConfigByUrl: async () => ({
|
||||||
|
wwwroot: 'https://campus.example.edu',
|
||||||
|
httpswwwroot: 'https://campus.example.edu',
|
||||||
|
sitename: 'Example Campus',
|
||||||
|
guestlogin: 0,
|
||||||
|
rememberusername: 0,
|
||||||
|
authloginviaemail: 0,
|
||||||
|
registerauth: '',
|
||||||
|
forgottenpasswordurl: '',
|
||||||
|
authinstructions: '',
|
||||||
|
authnoneenabled: 0,
|
||||||
|
enablewebservices: 1,
|
||||||
|
enablemobilewebservice: 1,
|
||||||
|
maintenanceenabled: 0,
|
||||||
|
maintenancemessage: '',
|
||||||
|
typeoflogin: 1,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
// Act.
|
// Act.
|
||||||
const fixture = await renderPageComponent(CoreLoginCredentialsPage, {
|
const fixture = await renderPageComponent(CoreLoginCredentialsPage, {
|
||||||
routeParams: { siteUrl },
|
routeParams: { siteUrl },
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import { Input, OnInit, ElementRef, Directive } from '@angular/core';
|
import { Input, OnInit, ElementRef, Directive } from '@angular/core';
|
||||||
|
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
||||||
|
@ -72,7 +73,12 @@ export class CoreSitePluginsCallWSOnClickBaseDirective extends CoreSitePluginsCa
|
||||||
await super.callWS();
|
await super.callWS();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.showError === undefined || CoreUtils.isTrueOrOne(this.showError)) {
|
if (this.showError === undefined || CoreUtils.isTrueOrOne(this.showError)) {
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'core.serverconnection', true);
|
CoreDomUtils.showErrorModalDefault(
|
||||||
|
error,
|
||||||
|
Translate.instant('core.serverconnection', {
|
||||||
|
details: CoreTextUtils.getErrorMessageFromError(error) ?? 'Unknown error',
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreSiteError } from '@classes/errors/siteerror';
|
||||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
||||||
|
@ -45,10 +46,12 @@ export default function(): void {
|
||||||
if (isExternalApp && url.includes('://token=')) {
|
if (isExternalApp && url.includes('://token=')) {
|
||||||
// It's an SSO token for another app. Close the IAB and show an error.
|
// It's an SSO token for another app. Close the IAB and show an error.
|
||||||
CoreUtils.closeInAppBrowser();
|
CoreUtils.closeInAppBrowser();
|
||||||
CoreDomUtils.showErrorModal(Translate.instant('core.login.contactyouradministratorissue', {
|
CoreDomUtils.showErrorModal(new CoreSiteError({
|
||||||
$a: '<br><br>' + Translate.instant('core.errorurlschemeinvalidscheme', {
|
contactSupport: true,
|
||||||
$a: urlScheme,
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
}),
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
|
errorcode: 'invalidurlscheme',
|
||||||
|
errorDetails: Translate.instant('core.errorurlschemeinvalidscheme', { $a: urlScheme }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"agelocationverification": "Age and location verification",
|
"agelocationverification": "Age and location verification",
|
||||||
"ago": "{{$a}} ago",
|
"ago": "{{$a}} ago",
|
||||||
"ajaxendpointnotfound": "<p>AJAX endpoint not found. This can happen if the Moodle site is too old or it blocks access to this endpoint. The Moodle app only supports Moodle systems {{$a}} onwards. Please contact your site administrator.</p>\n<p>{{whoisadmin}}</p>",
|
"ajaxendpointnotfound": "AJAX endpoint not found. This can happen if the Moodle site is too old or it blocks access to this endpoint. The Moodle app only supports Moodle systems {{$a}} onwards.",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"allgroups": "All groups",
|
"allgroups": "All groups",
|
||||||
"allparticipants": "All participants",
|
"allparticipants": "All participants",
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
"cannotconnecttrouble": "We're having trouble connecting to your site.",
|
"cannotconnecttrouble": "We're having trouble connecting to your site.",
|
||||||
"cannotconnecttroublewithoutsupport": "We're having trouble connecting to your site, please contact your institution.",
|
"cannotconnecttroublewithoutsupport": "We're having trouble connecting to your site, please contact your institution.",
|
||||||
"cannotconnectverify": "<strong>Please check the address is correct.</strong>",
|
"cannotconnectverify": "<strong>Please check the address is correct.</strong>",
|
||||||
"cannotdownloadfiles": "File downloading is disabled. Please contact your site administrator.",
|
"cannotdownloadfiles": "This institution has disabled downloading files.",
|
||||||
"cannotinstallapk": "For security reasons, you can't install unknown apps on your device from this app. Please open the file using a browser.",
|
"cannotinstallapk": "For security reasons, you can't install unknown apps on your device from this app. Please open the file using a browser.",
|
||||||
"cannotlogoutpageblocks": "Please save or discard your changes before continuing.",
|
"cannotlogoutpageblocks": "Please save or discard your changes before continuing.",
|
||||||
"cannotopeninapp": "This file may not work as expected on this device. Would you like to open it anyway?",
|
"cannotopeninapp": "This file may not work as expected on this device. Would you like to open it anyway?",
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
"captureimage": "Take picture",
|
"captureimage": "Take picture",
|
||||||
"capturevideo": "Record video",
|
"capturevideo": "Record video",
|
||||||
"category": "Category",
|
"category": "Category",
|
||||||
"certificaterror": "<p>The certificate of this site cannot be trusted by your device. Please contact your site administrator.</p>\n<p>{{whoisadmin}}</p>",
|
"certificaterror": "The certificate of this site cannot be trusted by your device: {{details}}",
|
||||||
"choose": "Choose",
|
"choose": "Choose",
|
||||||
"choosedots": "Choose...",
|
"choosedots": "Choose...",
|
||||||
"clearsearch": "Clear search",
|
"clearsearch": "Clear search",
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
"errordownloadingsomefiles": "Error downloading files. Some files might be missing.",
|
"errordownloadingsomefiles": "Error downloading files. Some files might be missing.",
|
||||||
"errorfileexistssamename": "A file with this name already exists.",
|
"errorfileexistssamename": "A file with this name already exists.",
|
||||||
"errorinvalidform": "The form contains invalid data. Please check that all required fields are filled in and that the data is valid.",
|
"errorinvalidform": "The form contains invalid data. Please check that all required fields are filled in and that the data is valid.",
|
||||||
"errorinvalidresponse": "Invalid response received. Please contact your site administrator if the error persists.",
|
"errorinvalidresponse": "Invalid response received for {{method}} webservice.",
|
||||||
"errorloadingcontent": "Error loading content.",
|
"errorloadingcontent": "Error loading content.",
|
||||||
"errorofflinedisabled": "Offline browsing is disabled on your site. You need to be connected to the internet to use the app.",
|
"errorofflinedisabled": "Offline browsing is disabled on your site. You need to be connected to the internet to use the app.",
|
||||||
"erroropenfiledownloading": "Error opening file: you need to wait for the download to complete.",
|
"erroropenfiledownloading": "Error opening file: you need to wait for the download to complete.",
|
||||||
|
@ -275,7 +275,7 @@
|
||||||
"selectagroup": "Select a group",
|
"selectagroup": "Select a group",
|
||||||
"send": "Send",
|
"send": "Send",
|
||||||
"sending": "Sending",
|
"sending": "Sending",
|
||||||
"serverconnection": "Error connecting to the server",
|
"serverconnection": "Error connecting to the server: {{details}}",
|
||||||
"show": "Show",
|
"show": "Show",
|
||||||
"showadvanced": "Show advanced",
|
"showadvanced": "Show advanced",
|
||||||
"showless": "Show less...",
|
"showless": "Show less...",
|
||||||
|
@ -353,7 +353,6 @@
|
||||||
"weeks": "weeks",
|
"weeks": "weeks",
|
||||||
"whatisyourage": "What is your age?",
|
"whatisyourage": "What is your age?",
|
||||||
"wheredoyoulive": "In which country do you live?",
|
"wheredoyoulive": "In which country do you live?",
|
||||||
"whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.",
|
|
||||||
"whyisthishappening": "Why is this happening?",
|
"whyisthishappening": "Why is this happening?",
|
||||||
"whyisthisrequired": "Why is this required?",
|
"whyisthisrequired": "Why is this required?",
|
||||||
"wsfunctionnotavailable": "The web service function is not available.",
|
"wsfunctionnotavailable": "The web service function is not available.",
|
||||||
|
|
|
@ -296,14 +296,14 @@ export class CoreSitesProvider {
|
||||||
|
|
||||||
// Check that the user can authenticate.
|
// Check that the user can authenticate.
|
||||||
if (!config.enablewebservices) {
|
if (!config.enablewebservices) {
|
||||||
throw this.createCannotConnectError({
|
throw this.createCannotConnectLoginError({
|
||||||
errorcode: 'webservicesnotenabled',
|
errorcode: 'webservicesnotenabled',
|
||||||
errorDetails: Translate.instant('core.login.webservicesnotenabled'),
|
errorDetails: Translate.instant('core.login.webservicesnotenabled'),
|
||||||
siteConfig: config,
|
siteConfig: config,
|
||||||
critical: true,
|
critical: true,
|
||||||
});
|
});
|
||||||
} else if (!config.enablemobilewebservice) {
|
} else if (!config.enablemobilewebservice) {
|
||||||
throw this.createCannotConnectError({
|
throw this.createCannotConnectLoginError({
|
||||||
errorcode: 'mobileservicesnotenabled',
|
errorcode: 'mobileservicesnotenabled',
|
||||||
errorDetails: Translate.instant('core.login.mobileservicesnotenabled'),
|
errorDetails: Translate.instant('core.login.mobileservicesnotenabled'),
|
||||||
siteConfig: config,
|
siteConfig: config,
|
||||||
|
@ -327,18 +327,29 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an error to be thrown when it isn't possible to connect to a site.
|
* Create an error to be thrown when it isn't possible to login to a site.
|
||||||
*
|
*
|
||||||
* @param options Error options.
|
* @param options Error options.
|
||||||
* @return Cannot connect error.
|
* @return Cannot connect error.
|
||||||
*/
|
*/
|
||||||
protected createCannotConnectError(options: Partial<CoreLoginErrorOptions> = {}): CoreLoginError {
|
protected createCannotConnectLoginError(options?: Partial<CoreLoginErrorOptions>): CoreLoginError;
|
||||||
return new CoreLoginError({
|
protected createCannotConnectLoginError(siteUrl: string, options?: Partial<CoreLoginErrorOptions>): Promise<CoreLoginError>;
|
||||||
|
protected createCannotConnectLoginError(
|
||||||
|
siteUrlOrOptions: string | Partial<CoreLoginErrorOptions> = {},
|
||||||
|
options: Partial<CoreLoginErrorOptions> = {},
|
||||||
|
): CoreLoginError | Promise<CoreLoginError> {
|
||||||
|
const createError = (options: Partial<CoreLoginErrorOptions>) => new CoreLoginError({
|
||||||
...options,
|
...options,
|
||||||
message: Translate.instant('core.cannotconnecttrouble'),
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
contactSupport: true,
|
contactSupport: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return typeof siteUrlOrOptions === 'object'
|
||||||
|
? createError(siteUrlOrOptions)
|
||||||
|
: CoreUtils
|
||||||
|
.ignoreErrors(this.getPublicSiteConfigByUrl(siteUrlOrOptions))
|
||||||
|
.then(siteConfig => createError({ ...options, siteConfig }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -361,31 +372,40 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service supported but an error happened. Return error.
|
// Service supported but an error happened. Return error.
|
||||||
let critical = true;
|
const options: CoreLoginErrorOptions = {
|
||||||
|
critical: true,
|
||||||
|
message: error.message,
|
||||||
|
errorcode: error.errorcode,
|
||||||
|
contactSupport: error.contactSupport,
|
||||||
|
siteConfig: error.siteConfig,
|
||||||
|
errorDetails: error.errorDetails,
|
||||||
|
};
|
||||||
|
|
||||||
if (error.errorcode === 'codingerror') {
|
if (error.errorcode === 'codingerror') {
|
||||||
// This could be caused by a redirect. Check if it's the case.
|
// This could be caused by a redirect. Check if it's the case.
|
||||||
const redirect = await CoreUtils.checkRedirect(siteUrl);
|
const redirect = await CoreUtils.checkRedirect(siteUrl);
|
||||||
|
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
error.message = Translate.instant('core.login.sitehasredirect');
|
options.message = Translate.instant('core.cannotconnecttrouble');
|
||||||
critical = false; // Keep checking fallback URLs.
|
options.fallbackMessage = Translate.instant('core.cannotconnecttroublewithoutsupport');
|
||||||
|
options.errorcode = 'sitehasredirect';
|
||||||
|
options.errorDetails = Translate.instant('core.login.sitehasredirect');
|
||||||
|
options.critical = false; // Keep checking fallback URLs.
|
||||||
} else {
|
} else {
|
||||||
// We can't be sure if there is a redirect or not. Display cannot connect error.
|
// We can't be sure if there is a redirect or not. Display cannot connect error.
|
||||||
error.message = Translate.instant('core.cannotconnecttrouble');
|
options.message = Translate.instant('core.cannotconnecttrouble');
|
||||||
}
|
}
|
||||||
} else if (error.errorcode === 'invalidrecord') {
|
} else if (error.errorcode === 'invalidrecord') {
|
||||||
// WebService not found, site not supported.
|
// WebService not found, site not supported.
|
||||||
error.message = Translate.instant('core.login.invalidmoodleversion', { $a: CoreSite.MINIMUM_MOODLE_VERSION });
|
options.message = Translate.instant('core.cannotconnecttrouble');
|
||||||
|
options.fallbackMessage = Translate.instant('core.cannotconnecttroublewithoutsupport');
|
||||||
|
options.errorcode = 'invalidmoodleversion';
|
||||||
|
options.errorDetails = Translate.instant('core.login.invalidmoodleversion', { $a: CoreSite.MINIMUM_MOODLE_VERSION });
|
||||||
} else if (error.errorcode === 'redirecterrordetected') {
|
} else if (error.errorcode === 'redirecterrordetected') {
|
||||||
critical = false; // Keep checking fallback URLs.
|
options.critical = false; // Keep checking fallback URLs.
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CoreLoginError({
|
return new CoreLoginError(options);
|
||||||
message: error.message,
|
|
||||||
errorcode: error.errorcode,
|
|
||||||
critical,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -405,33 +425,31 @@ export class CoreSitesProvider {
|
||||||
data = await Http.post(siteUrl + '/login/token.php', { appsitecheck: 1 }).pipe(timeout(CoreWS.getRequestTimeout()))
|
data = await Http.post(siteUrl + '/login/token.php', { appsitecheck: 1 }).pipe(timeout(CoreWS.getRequestTimeout()))
|
||||||
.toPromise();
|
.toPromise();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Default error messages are kinda bad, return our own message.
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
throw new CoreLoginError({
|
errorcode: 'sitecheckfailed',
|
||||||
message: Translate.instant('core.cannotconnecttrouble'),
|
errorDetails: CoreDomUtils.getErrorMessage(error) ?? undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data === null) {
|
if (data === null) {
|
||||||
// Cannot connect.
|
// Cannot connect.
|
||||||
throw new CoreLoginError({
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
message: Translate.instant('core.cannotconnect', { $a: CoreSite.MINIMUM_MOODLE_VERSION }),
|
errorcode: 'appsitecheckfailed',
|
||||||
|
errorDetails: 'A request to /login/token.php with appsitecheck=1 returned an empty response',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) {
|
if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) {
|
||||||
throw new CoreLoginError({
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
errorcode: data.errorcode,
|
errorcode: data.errorcode,
|
||||||
message: data.error ?? '',
|
errorDetails: data.error,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.error && data.error == 'Web services must be enabled in Advanced features.') {
|
if (data.error && data.error == 'Web services must be enabled in Advanced features.') {
|
||||||
const siteConfig = await CoreUtils.ignoreErrors(this.getPublicSiteConfigByUrl(siteUrl));
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
|
|
||||||
throw this.createCannotConnectError({
|
|
||||||
errorcode: 'enablewsdescription',
|
errorcode: 'enablewsdescription',
|
||||||
errorDetails: data.error,
|
errorDetails: data.error,
|
||||||
siteConfig,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,15 +509,16 @@ export class CoreSitesProvider {
|
||||||
const redirect = await CoreUtils.checkRedirect(loginUrl);
|
const redirect = await CoreUtils.checkRedirect(loginUrl);
|
||||||
|
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
throw new CoreLoginError({
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
message: Translate.instant('core.login.sitehasredirect'),
|
errorcode: 'sitehasredirect',
|
||||||
|
errorDetails: Translate.instant('core.login.sitehasredirect'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CoreLoginError({
|
throw await this.createCannotConnectLoginError(siteUrl, {
|
||||||
message: data.error,
|
|
||||||
errorcode: data.errorcode,
|
errorcode: data.errorcode,
|
||||||
|
errorDetails: data.error,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpResponse, HttpParams } from '@angular/common/http';
|
import { HttpResponse, HttpParams, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
import { FileEntry } from '@ionic-native/file/ngx';
|
import { FileEntry } from '@ionic-native/file/ngx';
|
||||||
import { FileUploadOptions, FileUploadResult } from '@ionic-native/file-transfer/ngx';
|
import { FileUploadOptions, FileUploadResult } from '@ionic-native/file-transfer/ngx';
|
||||||
|
@ -41,6 +41,7 @@ import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreSiteError, CoreSiteErrorOptions } from '@classes/errors/siteerror';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service allows performing WS calls and download/upload files.
|
* This service allows performing WS calls and download/upload files.
|
||||||
|
@ -477,7 +478,9 @@ export class CoreWSProvider {
|
||||||
message: Translate.instant('core.cannotconnecttrouble'),
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
errorcode: 'invalidresponse',
|
errorcode: 'invalidresponse',
|
||||||
errorDetails: Translate.instant('core.serverconnection'),
|
errorDetails: Translate.instant('core.serverconnection', {
|
||||||
|
details: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
} else if (data.error) {
|
} else if (data.error) {
|
||||||
throw new CoreAjaxWSError(data);
|
throw new CoreAjaxWSError(data);
|
||||||
|
@ -491,24 +494,34 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.data;
|
return data.data;
|
||||||
}, (data) => {
|
}, async (data: HttpErrorResponse) => {
|
||||||
let message = '';
|
const options: CoreSiteErrorOptions = {
|
||||||
|
contactSupport: true,
|
||||||
|
siteConfig: await CoreUtils.ignoreErrors(CoreSites.getPublicSiteConfigByUrl(preSets.siteUrl)),
|
||||||
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
|
};
|
||||||
|
|
||||||
switch (data.status) {
|
switch (data.status) {
|
||||||
case -2: // Certificate error.
|
case -2: // Certificate error.
|
||||||
message = this.getCertificateErrorMessage(data.error);
|
options.errorcode = 'invalidcertificate';
|
||||||
break;
|
options.errorDetails = Translate.instant('core.certificaterror', {
|
||||||
case 404: // AJAX endpoint not found.
|
details: CoreTextUtils.getErrorMessageFromError(data.error) ?? 'Unknown error',
|
||||||
message = Translate.instant('core.ajaxendpointnotfound', {
|
|
||||||
$a: CoreSite.MINIMUM_MOODLE_VERSION,
|
|
||||||
whoisadmin: Translate.instant('core.whoissiteadmin'),
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 404: // AJAX endpoint not found.
|
||||||
|
options.errorcode = 'endpointnotfound';
|
||||||
|
options.errorDetails = Translate.instant('core.ajaxendpointnotfound', { $a: CoreSite.MINIMUM_MOODLE_VERSION });
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
message = Translate.instant('core.serverconnection');
|
options.errorcode = 'serverconnectionajax';
|
||||||
|
options.errorDetails = Translate.instant('core.serverconnection', {
|
||||||
|
details: CoreTextUtils.getErrorMessageFromError(data.error) ?? 'Unknown error',
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CoreAjaxError(message, 1, data.status);
|
throw new CoreAjaxError(options, 1, data.status);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,7 +643,7 @@ export class CoreWSProvider {
|
||||||
const promise = Http.post(requestUrl, ajaxData, options).pipe(timeout(this.getRequestTimeout())).toPromise();
|
const promise = Http.post(requestUrl, ajaxData, options).pipe(timeout(this.getRequestTimeout())).toPromise();
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
return promise.then((data: any) => {
|
return promise.then(async (data: any) => {
|
||||||
// Some moodle web services return null.
|
// Some moodle web services return null.
|
||||||
// If the responseExpected value is set to false, we create a blank object if the response is null.
|
// If the responseExpected value is set to false, we create a blank object if the response is null.
|
||||||
if (!data && !preSets.responseExpected) {
|
if (!data && !preSets.responseExpected) {
|
||||||
|
@ -638,7 +651,12 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new CoreError(Translate.instant('core.serverconnection'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'serverconnectionpost',
|
||||||
|
errorDetails: Translate.instant('core.serverconnection', {
|
||||||
|
details: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
}),
|
||||||
|
});
|
||||||
} else if (typeof data != preSets.typeExpected) {
|
} else if (typeof data != preSets.typeExpected) {
|
||||||
// If responseType is text an string will be returned, parse before returning.
|
// If responseType is text an string will be returned, parse before returning.
|
||||||
if (typeof data == 'string') {
|
if (typeof data == 'string') {
|
||||||
|
@ -647,7 +665,10 @@ export class CoreWSProvider {
|
||||||
if (isNaN(data)) {
|
if (isNaN(data)) {
|
||||||
this.logger.warn(`Response expected type "${preSets.typeExpected}" cannot be parsed to number`);
|
this.logger.warn(`Response expected type "${preSets.typeExpected}" cannot be parsed to number`);
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (preSets.typeExpected == 'boolean') {
|
} else if (preSets.typeExpected == 'boolean') {
|
||||||
if (data === 'true') {
|
if (data === 'true') {
|
||||||
|
@ -657,17 +678,26 @@ export class CoreWSProvider {
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn(`Response expected type "${preSets.typeExpected}" is not true or false`);
|
this.logger.warn(`Response expected type "${preSets.typeExpected}" is not true or false`);
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`);
|
this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`);
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`);
|
this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`);
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +715,7 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}, (error) => {
|
}, async (error) => {
|
||||||
// If server has heavy load, retry after some seconds.
|
// If server has heavy load, retry after some seconds.
|
||||||
if (error.status == 429) {
|
if (error.status == 429) {
|
||||||
const retryPromise = this.addToRetryQueue<T>(method, siteUrl, ajaxData, preSets);
|
const retryPromise = this.addToRetryQueue<T>(method, siteUrl, ajaxData, preSets);
|
||||||
|
@ -708,7 +738,12 @@ 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 await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidcertificate',
|
||||||
|
errorDetails: Translate.instant('core.certificaterror', {
|
||||||
|
details: CoreTextUtils.getErrorMessageFromError(error) ?? 'Unknown error',
|
||||||
|
}),
|
||||||
|
});
|
||||||
} else if (error.status > 0) {
|
} else if (error.status > 0) {
|
||||||
throw this.createHttpError(error, error.status);
|
throw this.createHttpError(error, error.status);
|
||||||
}
|
}
|
||||||
|
@ -717,24 +752,6 @@ export class CoreWSProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get error message about certificate error.
|
|
||||||
*
|
|
||||||
* @param error Exact error message.
|
|
||||||
* @return Certificate error message.
|
|
||||||
*/
|
|
||||||
protected getCertificateErrorMessage(error?: string): string {
|
|
||||||
const message = Translate.instant('core.certificaterror', {
|
|
||||||
whoisadmin: Translate.instant('core.whoissiteadmin'),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return `${message}\n<p>${error}</p>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retry all requests in the queue.
|
* Retry all requests in the queue.
|
||||||
* This function uses recursion in order to add a delay between requests to reduce stress.
|
* This function uses recursion in order to add a delay between requests to reduce stress.
|
||||||
|
@ -850,10 +867,12 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new CoreError(Translate.instant('core.serverconnection'));
|
throw new CoreError(Translate.instant('core.serverconnection', {
|
||||||
|
details: Translate.instant('core.errorinvalidresponse', { method }),
|
||||||
|
}));
|
||||||
} else if (typeof data != preSets.typeExpected) {
|
} else if (typeof data != preSets.typeExpected) {
|
||||||
this.logger.warn('Response of type "' + typeof data + '" received, expecting "' + preSets.typeExpected + '"');
|
this.logger.warn('Response of type "' + typeof data + '" received, expecting "' + preSets.typeExpected + '"');
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw new CoreError(Translate.instant('core.errorinvalidresponse', { method }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.exception !== undefined || data.debuginfo !== undefined) {
|
if (data.exception !== undefined || data.debuginfo !== undefined) {
|
||||||
|
@ -923,15 +942,26 @@ export class CoreWSProvider {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data === null) {
|
if (data === null) {
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new CoreError(Translate.instant('core.serverconnection'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'serverconnectionupload',
|
||||||
|
errorDetails: Translate.instant('core.serverconnection', {
|
||||||
|
details: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }),
|
||||||
|
}),
|
||||||
|
});
|
||||||
} else if (typeof data != 'object') {
|
} else if (typeof data != 'object') {
|
||||||
this.logger.warn('Upload file: Response of type "' + typeof data + '" received, expecting "object"');
|
this.logger.warn('Upload file: Response of type "' + typeof data + '" received, expecting "object"');
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorinvalidresponse'));
|
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||||
|
errorcode: 'invalidresponse',
|
||||||
|
errorDetails: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.exception !== undefined) {
|
if (data.exception !== undefined) {
|
||||||
|
@ -1091,6 +1121,28 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an error to be thrown when it isn't possible to connect to a site.
|
||||||
|
*
|
||||||
|
* @param siteUrl Site url.
|
||||||
|
* @param options Error options.
|
||||||
|
* @return Cannot connect error.
|
||||||
|
*/
|
||||||
|
protected async createCannotConnectSiteError(
|
||||||
|
siteUrl: string,
|
||||||
|
options?: Partial<CoreSiteErrorOptions>,
|
||||||
|
): Promise<CoreSiteError> {
|
||||||
|
const siteConfig = await CoreUtils.ignoreErrors(CoreSites.getPublicSiteConfigByUrl(siteUrl));
|
||||||
|
|
||||||
|
return new CoreSiteError({
|
||||||
|
...options,
|
||||||
|
siteConfig,
|
||||||
|
message: Translate.instant('core.cannotconnecttrouble'),
|
||||||
|
fallbackMessage: Translate.instant('core.cannotconnecttroublewithoutsupport'),
|
||||||
|
contactSupport: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CoreWS = makeSingleton(CoreWSProvider);
|
export const CoreWS = makeSingleton(CoreWSProvider);
|
||||||
|
|
Loading…
Reference in New Issue