diff --git a/src/addons/blog/pages/edit-entry/edit-entry.ts b/src/addons/blog/pages/edit-entry/edit-entry.ts index 3858ebdbe..5f732f19c 100644 --- a/src/addons/blog/pages/edit-entry/edit-entry.ts +++ b/src/addons/blog/pages/edit-entry/edit-entry.ts @@ -41,7 +41,7 @@ import { CoreNetwork } from '@services/network'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSync } from '@services/sync'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { CoreForms } from '@singletons/form'; @@ -258,7 +258,7 @@ export default class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestr return selectedEntry; } catch (error) { - if (!params.filters || CoreUtils.isWebServiceError(error)) { + if (!params.filters || CoreWSError.isWebServiceError(error)) { // Cannot get the entry, reject. throw error; } @@ -336,7 +336,7 @@ export default class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestr return await this.saveEntry({ attachmentsId: attachmentsid }); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, the user cannot send the message so don't store it. CoreDomUtils.showErrorModalDefault(error, 'Error updating entry.'); @@ -361,7 +361,7 @@ export default class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestr const attachmentsId = await this.uploadOrStoreFiles({ created }); await this.saveEntry({ created, attachmentsId }); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, the user cannot send the message so don't store it. CoreDomUtils.showErrorModalDefault(error, 'Error creating entry.'); diff --git a/src/addons/blog/services/blog-sync.ts b/src/addons/blog/services/blog-sync.ts index 953ab5564..e34a43b18 100644 --- a/src/addons/blog/services/blog-sync.ts +++ b/src/addons/blog/services/blog-sync.ts @@ -17,7 +17,7 @@ import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync'; import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSync, CoreSyncResult } from '@services/sync'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { ADDON_BLOG_AUTO_SYNCED, ADDON_BLOG_SYNC_ID } from '../constants'; @@ -129,7 +129,7 @@ import { AddonBlogOfflineEntryDBRecord } from './database/blog'; await AddonBlogOffline.deleteOfflineEntryRecord({ created: entry.created }, siteId); result.updated = true; } catch (error) { - if (!error || !CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } @@ -223,7 +223,7 @@ import { AddonBlogOfflineEntryDBRecord } from './database/blog'; entriesToSync = entriesPendingToSync; } } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/blog/services/blog.ts b/src/addons/blog/services/blog.ts index 61e9db79c..45b5bb0b7 100644 --- a/src/addons/blog/services/blog.ts +++ b/src/addons/blog/services/blog.ts @@ -27,6 +27,7 @@ import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWar import { makeSingleton } from '@singletons'; import { AddonBlogOffline, AddonBlogOfflineEntry } from './blog-offline'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; const ROOT_CACHE_KEY = 'addonBlog:'; @@ -121,7 +122,7 @@ export class AddonBlogProvider { try { await this.addEntryOnline(params, siteId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, store in offline. return await storeOffline(); } @@ -177,7 +178,7 @@ export class AddonBlogProvider { try { await this.updateEntryOnline(params, siteId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, store in offline. return await storeOffline(); } @@ -232,7 +233,7 @@ export class AddonBlogProvider { await this.deleteEntryOnline(params, siteId); await CorePromiseUtils.ignoreErrors(AddonBlogOffline.unmarkEntryAsRemoved(params.entryid)); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, store in offline. return await AddonBlogOffline.markEntryAsRemoved({ id: params.entryid, subject }, siteId); } diff --git a/src/addons/calendar/services/calendar-sync.ts b/src/addons/calendar/services/calendar-sync.ts index e29ac63ce..d82383b8e 100644 --- a/src/addons/calendar/services/calendar-sync.ts +++ b/src/addons/calendar/services/calendar-sync.ts @@ -36,6 +36,7 @@ import { ADDON_CALENDAR_SYNC_ID, } from '../constants'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Service to sync calendar. @@ -219,7 +220,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider 0 || CoreUtils.isWebServiceError(error)) { + if (page > 0 || CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/mod/forum/components/post/post.ts b/src/addons/mod/forum/components/post/post.ts index da0d15195..d2d54aac7 100644 --- a/src/addons/mod/forum/components/post/post.ts +++ b/src/addons/mod/forum/components/post/post.ts @@ -59,6 +59,7 @@ import { CorePopovers } from '@services/popovers'; import { CoreLoadings } from '@services/loadings'; import { CoreWSFile } from '@services/ws'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.). @@ -554,7 +555,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges return { attachments, saveOffline: false }; } catch (error) { // Cannot upload them in online, save them in offline. - if (!this.forum.id || CoreUtils.isWebServiceError(error)) { + if (!this.forum.id || CoreWSError.isWebServiceError(error)) { // Cannot store them in offline. Reject. throw error; } diff --git a/src/addons/mod/forum/services/forum-helper.ts b/src/addons/mod/forum/services/forum-helper.ts index 734c589be..c796d23f3 100644 --- a/src/addons/mod/forum/services/forum-helper.ts +++ b/src/addons/mod/forum/services/forum-helper.ts @@ -33,6 +33,7 @@ import { AddonModForumDiscussionOptions, AddonModForumOffline, AddonModForumOffl import { CoreFileEntry } from '@services/file-helper'; import { ADDON_MOD_FORUM_ALL_GROUPS, ADDON_MOD_FORUM_COMPONENT } from '../constants'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Service that provides some features for forums. @@ -107,7 +108,7 @@ export class AddonModForumHelperProvider { try { await Promise.all(promises); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { throw error; } @@ -161,7 +162,7 @@ export class AddonModForumHelperProvider { if (errors.length == groupIds.length) { // All requests have failed. for (let i = 0; i < errors.length; i++) { - if (CoreUtils.isWebServiceError(errors[i]) || (attachments && attachments.length > 0)) { + if (CoreWSError.isWebServiceError(errors[i]) || (attachments && attachments.length > 0)) { // The WebService has thrown an error or offline not supported, reject. throw errors[i]; } diff --git a/src/addons/mod/forum/services/forum-sync.ts b/src/addons/mod/forum/services/forum-sync.ts index 261b07ec3..bcc5f1134 100644 --- a/src/addons/mod/forum/services/forum-sync.ts +++ b/src/addons/mod/forum/services/forum-sync.ts @@ -39,6 +39,7 @@ import { ADDON_MOD_FORUM_MANUAL_SYNCED, } from '../constants'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; declare module '@singletons/events' { @@ -273,7 +274,7 @@ export class AddonModForumSyncProvider extends CoreCourseActivitySyncBaseProvide if (errors.length === groupIds.length) { // All requests have failed, reject if errors were not returned by WS. for (const error of errors) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } } @@ -490,7 +491,7 @@ export class AddonModForumSyncProvider extends CoreCourseActivitySyncBaseProvide await this.deleteReply(forumId, reply.postid, siteId, userId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/mod/forum/services/forum.ts b/src/addons/mod/forum/services/forum.ts index 8ffbc4a9b..e933b4eee 100644 --- a/src/addons/mod/forum/services/forum.ts +++ b/src/addons/mod/forum/services/forum.ts @@ -51,6 +51,7 @@ import { } from '../constants'; import { CoreCacheUpdateFrequency } from '@/core/constants'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; declare module '@singletons/events' { @@ -1113,7 +1114,7 @@ export class AddonModForumProvider { return true; } catch (error) { - if (allowOffline && !CoreUtils.isWebServiceError(error)) { + if (allowOffline && !CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, store in offline. return storeOffline(); } else { diff --git a/src/addons/mod/glossary/pages/edit/edit.ts b/src/addons/mod/glossary/pages/edit/edit.ts index 4c2aa09fe..59b62abbc 100644 --- a/src/addons/mod/glossary/pages/edit/edit.ts +++ b/src/addons/mod/glossary/pages/edit/edit.ts @@ -25,7 +25,7 @@ import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreForms } from '@singletons/form'; @@ -522,7 +522,7 @@ class AddonModGlossaryNewFormHandler extends AddonModGlossaryFormHandler { try { onlineAttachments = await this.uploadAttachments(glossary); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/mod/glossary/services/glossary-sync.ts b/src/addons/mod/glossary/services/glossary-sync.ts index ab33c570f..faadf0159 100644 --- a/src/addons/mod/glossary/services/glossary-sync.ts +++ b/src/addons/mod/glossary/services/glossary-sync.ts @@ -22,7 +22,7 @@ import { CoreRatingSync } from '@features/rating/services/rating-sync'; import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; import { CoreSync, CoreSyncResult } from '@services/sync'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { AddonModGlossary } from './glossary'; @@ -207,7 +207,7 @@ export class AddonModGlossarySyncProvider extends CoreCourseActivitySyncBaseProv await this.deleteAddEntry(glossaryId, data.concept, data.timecreated, siteId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, reject. throw error; } diff --git a/src/addons/mod/glossary/services/glossary.ts b/src/addons/mod/glossary/services/glossary.ts index d7e3777e2..8e04dfc6c 100644 --- a/src/addons/mod/glossary/services/glossary.ts +++ b/src/addons/mod/glossary/services/glossary.ts @@ -39,6 +39,7 @@ import { } from '../constants'; import { CoreCacheUpdateFrequency } from '@/core/constants'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Service that provides some features for glossaries. @@ -874,7 +875,7 @@ export class AddonModGlossaryProvider { return entryId; } catch (error) { - if (otherOptions.allowOffline && !CoreUtils.isWebServiceError(error)) { + if (otherOptions.allowOffline && !CoreWSError.isWebServiceError(error)) { // Couldn't connect to server, store in offline. return storeOffline(); } diff --git a/src/addons/mod/h5pactivity/services/h5pactivity-sync.ts b/src/addons/mod/h5pactivity/services/h5pactivity-sync.ts index 93bb9c0c8..90f43d75b 100644 --- a/src/addons/mod/h5pactivity/services/h5pactivity-sync.ts +++ b/src/addons/mod/h5pactivity/services/h5pactivity-sync.ts @@ -22,7 +22,6 @@ import { CoreXAPIOffline } from '@features/xapi/services/offline'; import { CoreXAPI, XAPI_STATE_DELETED } from '@features/xapi/services/xapi'; import { CoreNetwork } from '@services/network'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { @@ -196,7 +195,7 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP h5pActivity = await AddonModH5PActivity.getH5PActivityByContextId(courseId, contextId, { siteId }); } catch (error) { if ( - CoreUtils.isWebServiceError(error) || + CoreWSError.isWebServiceError(error) || CoreErrorHelper.getErrorMessageFromError(error) === Translate.instant('core.course.modulenotfound') ) { // Activity no longer accessible. Delete the data and finish the sync. @@ -253,7 +252,7 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP await CoreXAPIOffline.deleteStatements(entry.id, siteId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } @@ -313,7 +312,7 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP } catch (error) { // Error getting attempts. If the WS has thrown an exception it means the user cannot retrieve the attempts for // some reason (it shouldn't happen), continue synchronizing in that case. - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } } @@ -364,7 +363,7 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP siteId, }); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/mod/h5pactivity/services/h5pactivity.ts b/src/addons/mod/h5pactivity/services/h5pactivity.ts index 68ebb7ab3..7065efe8e 100644 --- a/src/addons/mod/h5pactivity/services/h5pactivity.ts +++ b/src/addons/mod/h5pactivity/services/h5pactivity.ts @@ -16,7 +16,6 @@ import { Injectable } from '@angular/core'; import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites'; import { CoreWSExternalWarning, CoreWSExternalFile, CoreWSFile } from '@services/ws'; -import { CoreUtils } from '@services/utils/utils'; import { CoreSite } from '@classes/sites/site'; import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreH5P } from '@features/h5p/services/h5p'; @@ -380,7 +379,7 @@ export class AddonModH5PActivityProvider { return this.formatAttemptResults(response.attempts[0]); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { throw error; } @@ -634,7 +633,7 @@ export class AddonModH5PActivityProvider { return this.formatUserAttempts(response.usersattempts[0]); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { throw error; } diff --git a/src/addons/mod/lesson/pages/player/player.ts b/src/addons/mod/lesson/pages/player/player.ts index fd5b2be34..328921c0d 100644 --- a/src/addons/mod/lesson/pages/player/player.ts +++ b/src/addons/mod/lesson/pages/player/player.ts @@ -56,6 +56,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { ADDON_MOD_LESSON_COMPONENT, AddonModLessonJumpTo } from '../../constants'; import { CoreModals } from '@services/modals'; import { CorePromiseUtils } from '@singletons/promise-utils'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Page that allows attempting and reviewing a lesson. @@ -214,7 +215,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { throw error; } - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // WebService returned an error, cannot perform the action. throw error; } @@ -356,7 +357,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { return true; } catch (error) { - if (this.review && this.retakeToReview && CoreUtils.isWebServiceError(error)) { + if (this.review && this.retakeToReview && CoreWSError.isWebServiceError(error)) { // The user cannot review the retake. Unmark the retake as being finished in sync. await AddonModLessonSync.deleteRetakeFinishedInSync(this.lesson!.id); } diff --git a/src/addons/mod/lesson/pages/user-retake/user-retake.ts b/src/addons/mod/lesson/pages/user-retake/user-retake.ts index a76fdd9a1..8a7510062 100644 --- a/src/addons/mod/lesson/pages/user-retake/user-retake.ts +++ b/src/addons/mod/lesson/pages/user-retake/user-retake.ts @@ -20,7 +20,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreErrorHelper } from '@services/error-helper'; import { Translate } from '@singletons'; import { AddonModLesson, @@ -103,7 +103,7 @@ export class AddonModLessonUserRetakePage implements OnInit { this.performLogView(); } catch (error) { this.selectedRetake = this.previousSelectedRetake ?? this.selectedRetake; - CoreDomUtils.showErrorModal(CoreUtils.addDataNotDownloadedError(error, 'Error getting attempt.')); + CoreDomUtils.showErrorModal(CoreErrorHelper.addDataNotDownloadedError(error, 'Error getting attempt.')); } finally { this.loaded = true; } diff --git a/src/addons/mod/lesson/services/lesson-sync.ts b/src/addons/mod/lesson/services/lesson-sync.ts index 303f8df81..bdcfaf2d2 100644 --- a/src/addons/mod/lesson/services/lesson-sync.ts +++ b/src/addons/mod/lesson/services/lesson-sync.ts @@ -24,7 +24,7 @@ import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSync, CoreSyncResult } from '@services/sync'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { AddonModLessonRetakeFinishedInSyncDBRecord, RETAKES_FINISHED_SYNC_TABLE_NAME } from './database/lesson'; @@ -375,7 +375,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid await AddonModLessonOffline.deleteAttempt(lesson.id, retake, pageId, timemodified, siteId); } catch (error) { - if (!error || !CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server. throw error; } @@ -473,7 +473,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid await AddonModLessonOffline.deleteRetake(lessonId, siteId); } catch (error) { - if (!error || !CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Couldn't connect to server. throw error; } diff --git a/src/addons/mod/quiz/services/quiz-helper.ts b/src/addons/mod/quiz/services/quiz-helper.ts index 8e9ae6d2c..db7699497 100644 --- a/src/addons/mod/quiz/services/quiz-helper.ts +++ b/src/addons/mod/quiz/services/quiz-helper.ts @@ -20,7 +20,7 @@ import { CoreCourse } from '@features/course/services/course'; import { CoreNavigator } from '@services/navigator'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons'; import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate'; import { @@ -503,7 +503,7 @@ export class AddonModQuizHelperProvider { return attempt; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // The WebService returned an error, assume the preflight failed. AddonModQuizAccessRuleDelegate.notifyPreflightCheckFailed( rules, diff --git a/src/addons/mod/survey/services/survey-sync.ts b/src/addons/mod/survey/services/survey-sync.ts index e814a7427..d747a55aa 100644 --- a/src/addons/mod/survey/services/survey-sync.ts +++ b/src/addons/mod/survey/services/survey-sync.ts @@ -20,7 +20,7 @@ import { CoreCourse } from '@features/course/services/course'; import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { getPrefetchHandlerInstance } from './handlers/prefetch'; @@ -185,7 +185,7 @@ export class AddonModSurveySyncProvider extends CoreCourseActivitySyncBaseProvid // Answers sent, delete them. await AddonModSurveyOffline.deleteSurveyAnswers(surveyId, siteId, userId); } catch (error) { - if (!CoreUtils.isWebServiceError(error)) { + if (!CoreWSError.isWebServiceError(error)) { // Local error, reject. throw error; } diff --git a/src/addons/mod/survey/services/survey.ts b/src/addons/mod/survey/services/survey.ts index d781bdd4e..66e134471 100644 --- a/src/addons/mod/survey/services/survey.ts +++ b/src/addons/mod/survey/services/survey.ts @@ -19,7 +19,7 @@ import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreNetwork } from '@services/network'; import { CoreFilepool } from '@services/filepool'; import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { AddonModSurveyOffline } from './survey-offline'; @@ -268,7 +268,7 @@ export class AddonModSurveyProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, the user cannot send the message so don't store it. throw error; } diff --git a/src/addons/mod/wiki/services/wiki-sync.ts b/src/addons/mod/wiki/services/wiki-sync.ts index 82ab78842..31b43cd2c 100644 --- a/src/addons/mod/wiki/services/wiki-sync.ts +++ b/src/addons/mod/wiki/services/wiki-sync.ts @@ -20,7 +20,7 @@ import { CoreNetwork } from '@services/network'; import { CoreGroups } from '@services/groups'; import { CoreSites } from '@services/sites'; import { CoreSync, CoreSyncResult } from '@services/sync'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { AddonModWikiPageDBRecord } from './database/wiki'; @@ -248,7 +248,7 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, this means the user cannot send notes. errors.push(error); @@ -203,7 +203,7 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, this means the user cannot send notes. errors.push(error); diff --git a/src/addons/notes/services/notes.ts b/src/addons/notes/services/notes.ts index 89e935bad..802d4b9b1 100644 --- a/src/addons/notes/services/notes.ts +++ b/src/addons/notes/services/notes.ts @@ -17,7 +17,6 @@ import { CoreWSError } from '@classes/errors/wserror'; import { CoreUser } from '@features/user/services/user'; import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; import { CoreWSExternalWarning } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { AddonNotesOffline } from './notes-offline'; @@ -70,7 +69,7 @@ export class AddonNotesProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, the user cannot send the message so don't store it. throw error; } @@ -173,7 +172,7 @@ export class AddonNotesProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // It's a WebService error, the user cannot send the note so don't store it. throw error; } diff --git a/src/core/classes/element-controllers/MediaElementController.ts b/src/core/classes/element-controllers/MediaElementController.ts index 3a67a6ceb..b4b6682ad 100644 --- a/src/core/classes/element-controllers/MediaElementController.ts +++ b/src/core/classes/element-controllers/MediaElementController.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { CoreUtils } from '@services/utils/utils'; +import { CoreErrorHelper } from '@services/error-helper'; import { ElementController } from './ElementController'; import { CorePromisedValue } from '@classes/promised-value'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -70,7 +70,7 @@ export class MediaElementController extends ElementController { this.addPlaybackEventListeners(jsPlayer); } catch (error) { - CoreUtils.logUnhandledError('Error enabling media element', error); + CoreErrorHelper.logUnhandledError('Error enabling media element', error); } } diff --git a/src/core/classes/errors/wserror.ts b/src/core/classes/errors/wserror.ts index f34ac0587..c35d11b98 100644 --- a/src/core/classes/errors/wserror.ts +++ b/src/core/classes/errors/wserror.ts @@ -39,6 +39,39 @@ export class CoreWSError extends CoreError { this.backtrace = error.backtrace; } + /** + * Given an error returned by a WS call, check if the error is generated by the app or it has been returned by the WebService. + * + * @param error Error to check. + * @returns Whether the error was returned by the WebService. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static isWebServiceError(error: any): boolean { + return !!error && ( + error.warningcode !== undefined || + ( + error.errorcode !== undefined && error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' && + error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' && + error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' && + error.errorcode != 'wsaccessusersuspended' && error.errorcode != 'wsaccessuserdeleted' && + !this.isExpiredTokenError(error) + ) || + !!error.status && error.status >= 400 // CoreHttpError, assume status 400 and above are like WebService errors. + ); + } + + /** + * Given an error returned by a WS call, check if the error is a token expired error. + * + * @param error Error to check. + * @returns Whether the error is a token expired error. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static isExpiredTokenError(error: any): boolean { + return error.errorcode === 'invalidtoken' || + (error.errorcode === 'accessexception' && error.message.includes('Invalid token - token expired')); + } + } type CoreWSErrorData = { diff --git a/src/core/classes/sites/authenticated-site.ts b/src/core/classes/sites/authenticated-site.ts index 3f4858920..6dd5c30fb 100644 --- a/src/core/classes/sites/authenticated-site.ts +++ b/src/core/classes/sites/authenticated-site.ts @@ -642,7 +642,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite { } catch (error) { let useSilentError = false; - if (CoreUtils.isExpiredTokenError(error)) { + if (CoreWSError.isExpiredTokenError(error)) { // Session expired, trigger event. this.triggerSiteEvent(CoreEvents.SESSION_EXPIRED, {}); // Change error message. Try to get data from cache, the event will handle the error. @@ -719,7 +719,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite { throw new CoreWSError(error); } - if (preSets.deleteCacheIfWSError && CoreUtils.isWebServiceError(error)) { + if (preSets.deleteCacheIfWSError && CoreWSError.isWebServiceError(error)) { // Delete the cache entry and return the entry. Don't block the user with the delete. CorePromiseUtils.ignoreErrors(this.deleteFromCache(method, data, preSets)); @@ -785,7 +785,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite { try { return await this.callOrEnqueueRequest(method, data, preSets, wsPreSets); } catch (error) { - if (CoreUtils.isExpiredTokenError(error)) { + if (CoreWSError.isExpiredTokenError(error)) { if (initialToken !== this.token) { // Token has changed, retry with the new token. wsPreSets.wsToken = this.token ?? ''; diff --git a/src/core/directives/format-text.ts b/src/core/directives/format-text.ts index 47896df27..7257beb71 100644 --- a/src/core/directives/format-text.ts +++ b/src/core/directives/format-text.ts @@ -32,7 +32,7 @@ import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreIframeUtils, CoreIframeUtilsProvider } from '@services/utils/iframe'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreErrorHelper } from '@services/error-helper'; import { CoreSite } from '@classes/sites/site'; import { NgZone, Translate } from '@singletons'; import { CoreExternalContentDirective } from './external-content'; @@ -627,7 +627,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec } // Run asynchronous operations in the background to avoid blocking rendering. - Promise.all(promises).catch(error => CoreUtils.logUnhandledError('Error treating format-text elements', error)); + Promise.all(promises).catch(error => CoreErrorHelper.logUnhandledError('Error treating format-text elements', error)); return [ ...videoControllers, diff --git a/src/core/features/comments/services/comments-sync.ts b/src/core/features/comments/services/comments-sync.ts index d7e5df636..d6f933694 100644 --- a/src/core/features/comments/services/comments-sync.ts +++ b/src/core/features/comments/services/comments-sync.ts @@ -20,7 +20,7 @@ import { makeSingleton, Translate } from '@singletons'; import { CoreCommentsOffline } from './comments-offline'; import { CoreSites } from '@services/sites'; import { CoreNetwork } from '@services/network'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreCommentsDBRecord, CoreCommentsDeletedDBRecord } from './database/comments'; import { CoreSyncResult } from '@services/sync'; @@ -282,7 +282,7 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider('core_user_remove_user_device', data); } catch (error) { - if (CoreUtils.isWebServiceError(error) || CoreUtils.isExpiredTokenError(error)) { + if (CoreWSError.isWebServiceError(error) || CoreWSError.isExpiredTokenError(error)) { // Cannot unregister. Don't try again. await CorePromiseUtils.ignoreErrors(this.pendingUnregistersTable.delete({ token: site.getToken(), diff --git a/src/core/features/rating/services/rating-sync.ts b/src/core/features/rating/services/rating-sync.ts index 9e51a576f..0a9e5e54d 100644 --- a/src/core/features/rating/services/rating-sync.ts +++ b/src/core/features/rating/services/rating-sync.ts @@ -19,7 +19,7 @@ import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; import { CoreErrorHelper } from '@services/error-helper'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { CoreRating } from './rating'; @@ -222,7 +222,7 @@ export class CoreRatingSyncProvider extends CoreSyncBaseProvider { try { await CoreUser.setUserPreference(preference.name, preference.value, siteId); } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { const warning = CoreErrorHelper.getErrorMessageFromError(error); if (warning) { warnings.push(warning); diff --git a/src/core/features/xapi/services/xapi.ts b/src/core/features/xapi/services/xapi.ts index 553b5b803..4167abd71 100644 --- a/src/core/features/xapi/services/xapi.ts +++ b/src/core/features/xapi/services/xapi.ts @@ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; import { CoreNetwork } from '@services/network'; import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreWSError } from '@classes/errors/wserror'; import { CoreSite } from '@classes/sites/site'; import { CoreXAPIOffline, CoreXAPIOfflineSaveStatementsOptions } from './offline'; import { makeSingleton } from '@singletons'; @@ -121,7 +121,7 @@ export class CoreXAPIProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // The WebService has thrown an error, this means that the state cannot be deleted. throw error; } @@ -347,7 +347,7 @@ export class CoreXAPIProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // The WebService has thrown an error, this means that statements cannot be submitted. throw error; } else { @@ -421,7 +421,7 @@ export class CoreXAPIProvider { return true; } catch (error) { - if (CoreUtils.isWebServiceError(error)) { + if (CoreWSError.isWebServiceError(error)) { // The WebService has thrown an error, this means that state cannot be submitted. throw error; } diff --git a/src/core/services/error-helper.ts b/src/core/services/error-helper.ts index daadb2382..3d82a7672 100644 --- a/src/core/services/error-helper.ts +++ b/src/core/services/error-helper.ts @@ -16,6 +16,7 @@ import { Injectable } from '@angular/core'; import { CoreAnyError, CoreError } from '@classes/errors/error'; import { makeSingleton, Translate } from '@singletons'; import { AlertButton } from '@ionic/angular'; +import { CoreWSError } from '@classes/errors/wserror'; /** * Provider to provide some helper functions regarding files and packages. @@ -23,6 +24,24 @@ import { AlertButton } from '@ionic/angular'; @Injectable({ providedIn: 'root' }) export class CoreErrorHelperService { + /** + * Given an error, add an extra warning to the error message and return the new error message. + * + * @param error Error object or message. + * @param defaultError Message to show if the error is not a string. + * @returns New error message. + */ + addDataNotDownloadedError(error: Error | string, defaultError?: string): string { + const errorMessage = CoreErrorHelper.getErrorMessageFromError(error) || defaultError || ''; + + if (CoreWSError.isWebServiceError(error)) { + return errorMessage; + } + + // Local error. Add an extra warning. + return errorMessage + '

' + Translate.instant('core.errorsomedatanotdownloaded'); + } + /** * Add some text to an error message. * @@ -158,6 +177,17 @@ export class CoreErrorHelperService { return element?.innerText.trim() ?? ''; } + /** + * Log an unhandled error. + * + * @param message Message to contextualize the error. + * @param error Error to log. + */ + logUnhandledError(message: string, error: unknown): void { + // eslint-disable-next-line no-console + console.error('Unhandled error: '+message, error); + } + } export const CoreErrorHelper = makeSingleton(CoreErrorHelperService); diff --git a/src/core/services/urlschemes.ts b/src/core/services/urlschemes.ts index 35c419d95..f7131a788 100644 --- a/src/core/services/urlschemes.ts +++ b/src/core/services/urlschemes.ts @@ -29,7 +29,6 @@ import { CoreSiteCheckResponse, CoreSites } from './sites'; import { CoreDomUtils } from './utils/dom'; import { CoreErrorHelper, CoreErrorObject } from './error-helper'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from './utils/utils'; import { CoreLoadings } from './loadings'; /* @@ -494,7 +493,7 @@ export class CoreCustomURLSchemesProvider { treatHandleCustomURLError(error: CoreCustomURLSchemesHandleError): void { if (error.error == 'Duplicated') { // Duplicated request - } else if (CoreUtils.isWebServiceError(error.error) && error.data && error.data.isSSOToken) { + } else if (CoreWSError.isWebServiceError(error.error) && error.data && error.data.isSSOToken) { // An error occurred, display the error and logout the user. CoreLoginHelper.treatUserTokenError(error.data.siteUrl, error.error); CoreSites.logout(); diff --git a/src/core/services/utils/utils.ts b/src/core/services/utils/utils.ts index ddf5aa58f..aef33eabe 100644 --- a/src/core/services/utils/utils.ts +++ b/src/core/services/utils/utils.ts @@ -62,16 +62,10 @@ export class CoreUtilsProvider { * @param error Error object or message. * @param defaultError Message to show if the error is not a string. * @returns New error message. + * @deprecated since 5.0. Use CoreErrorHelper.addDataNotDownloadedError instead. */ addDataNotDownloadedError(error: Error | string, defaultError?: string): string { - const errorMessage = CoreErrorHelper.getErrorMessageFromError(error) || defaultError || ''; - - if (this.isWebServiceError(error)) { - return errorMessage; - } - - // Local error. Add an extra warning. - return errorMessage + '

' + Translate.instant('core.errorsomedatanotdownloaded'); + return CoreErrorHelper.addDataNotDownloadedError(error, defaultError); } /** @@ -123,9 +117,10 @@ export class CoreUtilsProvider { * * @param message Message to contextualize the error. * @param error Error to log. + * @deprecated since 5.0. Use CoreErrorHelper.logUnhandledError instead. */ logUnhandledError(message: string, error: unknown): void { - this.logger.error(message, error); + CoreErrorHelper.logUnhandledError(message, error); } /** @@ -828,6 +823,7 @@ export class CoreUtilsProvider { * * @param error Error to check. * @returns Whether the error was returned by the WebService. + * @deprecated since 5.0. Use CoreWSError.isWebServiceError instead. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isWebServiceError(error: any): boolean { @@ -838,6 +834,7 @@ export class CoreUtilsProvider { error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' && error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' && error.errorcode != 'wsaccessusersuspended' && error.errorcode != 'wsaccessuserdeleted' && + // eslint-disable-next-line deprecation/deprecation !this.isExpiredTokenError(error) ) || error.status && error.status >= 400 // CoreHttpError, assume status 400 and above are like WebService errors. @@ -849,6 +846,7 @@ export class CoreUtilsProvider { * * @param error Error to check. * @returns Whether the error is a token expired error. + * @deprecated since 5.0. Use CoreWSError.isExpiredTokenError instead. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isExpiredTokenError(error: any): boolean {