MOBILE-4047 cron: Improve alerts on cron failures

main
Pau Ferrer Ocaña 2022-06-14 17:55:15 +02:00
parent 842faa30c6
commit c1cae77bbc
11 changed files with 59 additions and 34 deletions

View File

@ -1705,7 +1705,9 @@
"core.erroropenfilenoextension": "local_moodlemobileapp",
"core.erroropenpopup": "local_moodlemobileapp",
"core.errorrenamefile": "local_moodlemobileapp",
"core.errorsitesupport": "local_moodlemobileapp",
"core.errorsomedatanotdownloaded": "local_moodlemobileapp",
"core.errorsomethingwrong": "local_moodlemobileapp",
"core.errorsync": "local_moodlemobileapp",
"core.errorsyncblocked": "local_moodlemobileapp",
"core.errorurlschemeinvalidscheme": "local_moodlemobileapp",
@ -2202,7 +2204,6 @@
"core.settings.enablerichtexteditordescription": "local_moodlemobileapp",
"core.settings.enablesyncwifi": "local_moodlemobileapp",
"core.settings.entriesincache": "local_moodlemobileapp",
"core.settings.errorsyncsite": "local_moodlemobileapp",
"core.settings.estimatedfreespace": "local_moodlemobileapp",
"core.settings.filesystemroot": "local_moodlemobileapp",
"core.settings.fontsize": "local_moodlemobileapp",
@ -2233,6 +2234,7 @@
"core.settings.showdownloadoptions": "local_moodlemobileapp",
"core.settings.siteinfo": "local_moodlemobileapp",
"core.settings.sites": "moodle",
"core.settings.sitesyncfailed": "local_moodlemobileapp",
"core.settings.spaceusage": "local_moodlemobileapp",
"core.settings.synchronization": "local_moodlemobileapp",
"core.settings.synchronizenow": "local_moodlemobileapp",

View File

@ -177,7 +177,9 @@ export class CoreCourseProvider {
CorePlatform.resume.subscribe(() => {
// Run the handler the app is open to keep user in online status.
setTimeout(() => {
CoreCronDelegate.forceCronHandlerExecution(CoreCourseLogCronHandler.name);
CoreUtils.ignoreErrors(
CoreCronDelegate.forceCronHandlerExecution(CoreCourseLogCronHandler.name),
);
}, 1000);
});

View File

@ -746,11 +746,7 @@ export class CorePushNotificationsProvider {
CoreEvents.trigger(CoreEvents.DEVICE_REGISTERED_IN_MOODLE, {}, site.getId());
// Insert the device in the local DB.
try {
await this.registeredDevicesTables[site.getId()].insert(data);
} catch (err) {
// Ignore errors.
}
await CoreUtils.ignoreErrors(this.registeredDevicesTables[site.getId()].insert(data));
}
} finally {
// Remove pending unregisters for this site.

View File

@ -4,8 +4,8 @@
"appsettings": "App settings",
"appversion": "App version",
"cannotsyncloggedout": "This site cannot be synchronised because you've logged out. Please try again when you're logged in the site again.",
"cannotsyncoffline": "Cannot synchronise offline.",
"cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
"cannotsyncoffline": "Site synchronisation failed because your device is not connected to the internet.",
"cannotsyncwithoutwifi": "Your device is not connected to Wi-Fi. Connect to a Wi-Fi network or turn off Data Saver in the app settings.",
"changelanguage": "Change to {{$a}}",
"changelanguagealert": "Changing the language will restart the app.",
"colorscheme-dark": "Dark",
@ -37,7 +37,6 @@
"enablerichtexteditordescription": "If enabled, a text editor will be available when entering content.",
"enablesyncwifi": "Allow sync only when on Wi-Fi",
"entriesincache": "{{$a}} entries in cache",
"errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.",
"estimatedfreespace": "Estimated free space",
"filesystemroot": "File system root",
"fontsize": "Text size",
@ -68,6 +67,7 @@
"showdownloadoptions": "Show download options",
"siteinfo": "Site info",
"sites": "Sites",
"sitesyncfailed": "Site synchronisation failed",
"spaceusage": "Space usage",
"synchronization": "Synchronisation",
"synchronizenow": "Synchronise now",

View File

@ -94,7 +94,7 @@ export class CoreSitePreferencesPage implements AfterViewInit, OnDestroy {
if (this.isDestroyed) {
return;
}
CoreDomUtils.showErrorModalDefault(error, 'core.settings.errorsyncsite', true);
CoreDomUtils.showErrorModalDefault(error, 'core.settings.sitesyncfailed', true);
}
}

View File

@ -95,7 +95,7 @@ export class CoreSettingsSynchronizationPage implements OnInit, OnDestroy {
return;
}
CoreDomUtils.showErrorModalDefault(error, 'core.settings.errorsyncsite', true);
CoreDomUtils.showErrorModalDefault(error, 'core.settings.sitesyncfailed', true);
}
}

View File

@ -29,6 +29,7 @@ import { CoreCourse } from '@features/course/services/course';
import { makeSingleton, Translate } from '@singletons';
import { CoreError } from '@classes/errors/error';
import { Observable, Subject } from 'rxjs';
import { CoreTextUtils } from '@services/utils/text';
/**
* Object with space usage and cache entries that can be erased.
@ -260,6 +261,7 @@ export class CoreSettingsHelperProvider {
const site = await CoreSites.getSite(siteId);
const hasSyncHandlers = CoreCronDelegate.hasManualSyncHandlers();
// All these errors should not happen on manual sync because are prevented on UI.
if (site.isLoggedOut()) {
// Cannot sync logged out sites.
throw new CoreError(Translate.instant('core.settings.cannotsyncloggedout'));
@ -286,6 +288,8 @@ export class CoreSettingsHelperProvider {
try {
await syncPromise;
} catch (error) {
throw CoreTextUtils.addTitleToError(error, Translate.instant('core.settings.sitesyncfailed'));
} finally {
delete this.syncPromises[siteId];
}

View File

@ -96,6 +96,7 @@
"downloading": "Downloading",
"edit": "Edit",
"emptysplit": "This page will appear blank if the left panel is empty or is loading.",
"endonesteptour": "Got it",
"error": "Error",
"errorchangecompletion": "An error occurred while changing the completion status. Please try again.",
"errordeletefile": "Error deleting the file. Please try again.",
@ -111,7 +112,9 @@
"erroropenfilenoextension": "Error opening file: the file doesn't have an extension.",
"erroropenpopup": "This activity is trying to open a popup. This is not supported in the app.",
"errorrenamefile": "Error renaming file. Please try again.",
"errorsitesupport": "If the problem persists, contact site support.",
"errorsomedatanotdownloaded": "If you downloaded this activity, please notice that some data isn't downloaded during the download process for performance and data usage reasons.",
"errorsomethingwrong": "Something went wrong. Please try again.",
"errorsync": "An error occurred while synchronising. Please try again.",
"errorsyncblocked": "This {{$a}} cannot be synchronised right now because of an ongoing process. Please try again later. If the problem persists, try restarting the app.",
"errorurlschemeinvalidscheme": "This URL is meant to be used in another app: {{$a}}.",
@ -248,8 +251,8 @@
"resources": "Resources",
"restore": "Restore",
"restricted": "Restricted",
"retry": "Retry",
"resume": "Resume",
"retry": "Retry",
"save": "Save",
"savechanges": "Save changes",
"scanqr": "Scan QR code",
@ -328,11 +331,10 @@
"user": "User",
"userdeleted": "This user account has been deleted",
"userdetails": "User details",
"usernotfullysetup": "User not fully set-up",
"usernologin": "Authentication has been revoked for this account",
"usersuspended": "Registration suspended",
"endonesteptour": "Got it",
"usernotfullysetup": "User not fully set-up",
"users": "Users",
"usersuspended": "Registration suspended",
"view": "View",
"viewcode": "View code",
"vieweditor": "View editor",
@ -351,8 +353,8 @@
"year": "year",
"years": "years",
"yes": "Yes",
"youreoffline": "You are offline",
"youreonline": "You are back online",
"youreoffline": "Your device is offline",
"youreonline": "Your device is back online",
"zoomin": "Zoom In",
"zoomout": "Zoom Out"
}

View File

@ -21,7 +21,7 @@ import { CoreUtils } from '@services/utils/utils';
import { CoreConstants } from '@/core/constants';
import { CoreError } from '@classes/errors/error';
import { makeSingleton } from '@singletons';
import { makeSingleton, Translate } from '@singletons';
import { CoreLogger } from '@singletons/logger';
import { APP_SCHEMA, CRON_TABLE_NAME, CronDBEntry } from '@services/database/cron';
import { asyncInstance } from '../utils/async-instance';
@ -81,10 +81,11 @@ export class CoreCronDelegateService {
protected async checkAndExecuteHandler(name: string, force?: boolean, siteId?: string): Promise<void> {
if (!this.handlers[name] || !this.handlers[name].execute) {
// Invalid handler.
const message = `Cannot execute handler because is invalid: ${name}`;
this.logger.debug(message);
this.logger.debug(`Cannot execute cron job because is invalid: ${name}`);
throw new CoreError(message);
throw new CoreError(
Translate.instant('core.errorsomethingwrong') + '<br>' + Translate.instant('core.errorsitesupport'),
);
}
const usesNetwork = this.handlerUsesNetwork(name);
@ -92,11 +93,10 @@ export class CoreCronDelegateService {
if (usesNetwork && !CoreNetwork.isOnline()) {
// Offline, stop executing.
const message = `Cannot execute handler because device is offline: ${name}`;
this.logger.debug(message);
this.logger.debug(`Cron job failed because your device is not connected to the internet: ${name}`);
this.stopHandler(name);
throw new CoreError(message);
throw new CoreError(Translate.instant('core.settings.cannotsyncoffline'));
}
if (isSync) {
@ -105,11 +105,10 @@ export class CoreCronDelegateService {
if (syncOnlyOnWifi && !CoreNetwork.isWifi()) {
// Cannot execute in this network connection, retry soon.
const message = `Cannot execute handler because device is using limited connection: ${name}`;
this.logger.debug(message);
this.logger.debug(`Cron job failed because your device has a limited internet connection: ${name}`);
this.scheduleNextExecution(name, CoreCronDelegateService.MIN_INTERVAL);
throw new CoreError(message);
throw new CoreError(Translate.instant('core.settings.cannotsyncwithoutwifi'));
}
}
@ -118,7 +117,7 @@ export class CoreCronDelegateService {
try {
await this.executeHandler(name, force, siteId);
this.logger.debug(`Execution of handler '${name}' was a success.`);
this.logger.debug(`Cron job '${name}' was successfully executed.`);
await CoreUtils.ignoreErrors(this.setHandlerLastExecutionTime(name, Date.now()));
@ -127,11 +126,10 @@ export class CoreCronDelegateService {
return;
} catch (error) {
// Handler call failed. Retry soon.
const message = `Execution of handler '${name}' failed.`;
this.logger.error(message, error);
this.logger.error(`Cron job '${name}' failed.`, error);
this.scheduleNextExecution(name, CoreCronDelegateService.MIN_INTERVAL);
throw new CoreError(message);
throw error;
}
});

View File

@ -46,7 +46,6 @@ import { CoreViewerImageComponent } from '@features/viewer/components/image/imag
import { CoreFormFields, CoreForms } from '../../singletons/form';
import { CoreModalLateralTransitionEnter, CoreModalLateralTransitionLeave } from '@classes/modal-lateral-transition';
import { CoreZoomLevel } from '@features/settings/services/settings-helper';
import { CoreErrorWithTitle } from '@classes/errors/errorwithtitle';
import { AddonFilterMultilangHandler } from '@addons/filter/multilang/services/handlers/multilang';
import { CoreSites } from '@services/sites';
import { NavigationStart } from '@angular/router';
@ -1350,7 +1349,7 @@ export class CoreDomUtilsProvider {
if (this.isNetworkError(message, error)) {
alertOptions.cssClass = 'core-alert-network-error';
} else if (error instanceof CoreErrorWithTitle) {
} else if (typeof error !== 'string' && 'title' in error) {
alertOptions.header = error.title || undefined;
} else {
alertOptions.header = Translate.instant('core.error');

View File

@ -37,6 +37,7 @@ export type CoreTextErrorObject = {
body?: string;
debuginfo?: string;
backtrace?: string;
title?: string;
};
/*
@ -149,6 +150,27 @@ export class CoreTextUtilsProvider {
return error;
}
/**
* Add some title to an error message.
*
* @param error Error message or object.
* @param title Title to add.
* @return Modified error.
*/
addTitleToError(error: string | CoreError | CoreTextErrorObject | undefined | null, title: string): CoreTextErrorObject {
let improvedError: CoreTextErrorObject = {};
if (typeof error === 'string') {
improvedError.message = error;
} else if (error && 'message' in error) {
improvedError = error;
}
improvedError.title = title;
return improvedError;
}
/**
* Given an address as a string, return a URL to open the address in maps.
*