mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 18:51:26 +00:00
improved error handling
This commit is contained in:
@@ -15,6 +15,7 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.beans.binding.StringExpression;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.util.Duration;
|
||||
@@ -40,13 +41,14 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
private final Environment env;
|
||||
private final Settings settings;
|
||||
private final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
|
||||
private final StringExpression latestVersion = StringExpression.stringExpression(lastValueProperty().map(UpdateInfo::version));
|
||||
private final BooleanBinding updateAvailable = lastValueProperty().isNotNull();
|
||||
private final ObjectProperty<UpdateInfo<?>> update = new SimpleObjectProperty<>();
|
||||
private final StringExpression latestVersion = StringExpression.stringExpression(update.map(UpdateInfo::version));
|
||||
private final BooleanBinding updateAvailable = update.isNotNull();
|
||||
private final ObjectBinding<UpdateCheckState> updateState = Bindings.createObjectBinding(this::getUpdateCheckState, stateProperty());
|
||||
private final BooleanBinding checkFailed = Bindings.equal(UpdateCheckState.CHECK_FAILED, updateState);
|
||||
private final HttpClient httpClient;
|
||||
private final UpdateMechanism<?> primaryUpdateMechanism;
|
||||
private final UpdateMechanism<?> fallbackUpdateMechanism;
|
||||
private UpdateMechanism<?> updateMechanism;
|
||||
|
||||
@Inject
|
||||
UpdateChecker(Settings settings, //
|
||||
@@ -63,9 +65,9 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
var currentVersion = env.getAppVersionWithBuildNumber();
|
||||
var lastAttemptedBy = settings.lastUpdateAttemptedByVersion.get();
|
||||
if (currentVersion != null && currentVersion.equals(lastAttemptedBy)) {
|
||||
this.primaryUpdateMechanism = fallbackUpdateMechanism; // immediately use fallback mechanism
|
||||
this.updateMechanism = fallbackUpdateMechanism; // immediately use fallback mechanism
|
||||
} else {
|
||||
this.primaryUpdateMechanism = UpdateMechanism.get().orElse(fallbackUpdateMechanism);
|
||||
this.updateMechanism = UpdateMechanism.get().orElse(fallbackUpdateMechanism);
|
||||
}
|
||||
|
||||
setExecutor(Executors.newVirtualThreadPerTaskExecutor());
|
||||
@@ -78,6 +80,14 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
public void recheckWithFallbackMechanism() {
|
||||
if (updateMechanism == fallbackUpdateMechanism) {
|
||||
return; // already using fallback mechanism
|
||||
}
|
||||
updateMechanism = fallbackUpdateMechanism;
|
||||
checkForUpdatesNow();
|
||||
}
|
||||
|
||||
public void checkForUpdatesNow() {
|
||||
startCheckingForUpdates(Duration.ZERO);
|
||||
}
|
||||
@@ -96,6 +106,7 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
lastSuccessfulUpdateCheck.set(Instant.now());
|
||||
if (updateInfo != null) {
|
||||
LOG.info("Current version: {}, latest version: {}", getCurrentVersion(), updateInfo.version());
|
||||
update.set(updateInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +117,14 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
|
||||
/* Observable Properties */
|
||||
|
||||
public UpdateInfo<?> getUpdate() {
|
||||
return update.get();
|
||||
}
|
||||
|
||||
public ObjectProperty<UpdateInfo<?>> updateProperty() {
|
||||
return update;
|
||||
}
|
||||
|
||||
public String getLatestVersion() {
|
||||
return latestVersion.get();
|
||||
}
|
||||
@@ -160,14 +179,14 @@ public class UpdateChecker extends ScheduledService<UpdateInfo<?>> {
|
||||
@Override
|
||||
protected UpdateInfo<?> call() {
|
||||
try {
|
||||
var result = primaryUpdateMechanism.checkForUpdate(env.getAppVersion(), httpClient);
|
||||
var result = updateMechanism.checkForUpdate(env.getAppVersion(), httpClient);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
} catch (UpdateFailedException e) {
|
||||
LOG.error("Primary update check failed.", e);
|
||||
LOG.error("Update check using {} failed.", updateMechanism.getClass(), e);
|
||||
}
|
||||
if (primaryUpdateMechanism == fallbackUpdateMechanism) {
|
||||
if (updateMechanism == fallbackUpdateMechanism) {
|
||||
return null;
|
||||
}
|
||||
LOG.debug("Trying fallback update check...");
|
||||
|
||||
@@ -75,7 +75,7 @@ public class UpdatesPreferencesController implements FxController {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.settings = settings;
|
||||
this.updateChecker = updateChecker;
|
||||
this.updateService = new UpdateService(updateChecker.lastValueProperty());
|
||||
this.updateService = new UpdateService(updateChecker.updateProperty());
|
||||
this.vaultService = vaultService;
|
||||
this.worker = Bindings.when(updateChecker.updateAvailableProperty()).<Worker<?>>then(this.updateService).otherwise(this.updateChecker);
|
||||
this.running = Bindings.createBooleanBinding(this::isRunning, updateService.stateProperty(), updateChecker.stateProperty());
|
||||
@@ -84,7 +84,7 @@ public class UpdatesPreferencesController implements FxController {
|
||||
this.timeDifferenceMessage = Bindings.createStringBinding(this::getTimeDifferenceMessage, updateChecker.lastSuccessfulUpdateCheckProperty());
|
||||
this.lastUpdateCheckMessage = Bindings.createStringBinding(this::getLastUpdateCheckMessage, updateChecker.lastSuccessfulUpdateCheckProperty());
|
||||
this.unlockedVaults = vaults.filtered(Vault::isUnlocked);
|
||||
this.prohibitUpdateWhileUnlocked = Bindings.createBooleanBinding(this::isProhibitUpdateWhileUnlocked, unlockedVaults, updateChecker.lastValueProperty());
|
||||
this.prohibitUpdateWhileUnlocked = Bindings.createBooleanBinding(this::isProhibitUpdateWhileUnlocked, unlockedVaults, updateChecker.updateProperty());
|
||||
this.updateButtonDisabled = Bindings.when(worker.isEqualTo(updateChecker)).then(running).otherwise(prohibitUpdateWhileUnlocked.or(running));
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ public class UpdatesPreferencesController implements FxController {
|
||||
} else if (!unlockedVaults.isEmpty()) {
|
||||
LOG.warn("Cannot start update due to unlocked vaults.");
|
||||
} else if (worker.get().equals(updateService)) {
|
||||
LOG.info("User started update to version {}", updateChecker.getLastValue().version());
|
||||
LOG.info("User started update to version {}", updateChecker.getUpdate().version());
|
||||
updateService.start();
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,8 @@ public class UpdatesPreferencesController implements FxController {
|
||||
private void updateFailed(WorkerStateEvent workerStateEvent) {
|
||||
assert workerStateEvent.getSource() == updateService;
|
||||
LOG.error("Update failed.", updateService.getException());
|
||||
// TODO: show error to user? use fallback update service?
|
||||
// try fallback mechanism:
|
||||
updateChecker.recheckWithFallbackMechanism();
|
||||
updateService.reset();
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ public class UpdatesPreferencesController implements FxController {
|
||||
return resourceBundle.getString("preferences.updates.checkNowBtn");
|
||||
} else {
|
||||
return switch (updateService.getState()) {
|
||||
case READY -> updateChecker.getLastValue().updateMechanism().getName();
|
||||
case READY -> updateChecker.getUpdate().updateMechanism().getName();
|
||||
case SCHEDULED, RUNNING -> updateService.getMessage(); // "Preparing Update..."; // TODO: resourceBundle.getString("preferences.updates.preparingUpdate")...
|
||||
case SUCCEEDED -> "Restart to Update"; // TODO: resourceBundle.getString("preferences.updates.readyToRestart")...
|
||||
case FAILED, CANCELLED -> "failed";
|
||||
@@ -234,7 +235,7 @@ public class UpdatesPreferencesController implements FxController {
|
||||
|
||||
public boolean isProhibitUpdateWhileUnlocked() {
|
||||
// If the result of the last update check was from the fallback mechanism, we don't need to show the warning
|
||||
return !unlockedVaults.isEmpty() && !FallbackUpdateInfo.class.isInstance(updateChecker.getLastValue());
|
||||
return !unlockedVaults.isEmpty() && !FallbackUpdateInfo.class.isInstance(updateChecker.getUpdate());
|
||||
}
|
||||
|
||||
public BooleanBinding prohibitUpdateWhileUnlockedProperty() {
|
||||
|
||||
Reference in New Issue
Block a user