Refactored handling of unexpected errors

This commit is contained in:
Sebastian Stenzel
2020-03-10 09:25:15 +01:00
parent cdb0fb37a9
commit 7fc5b1e55f
22 changed files with 188 additions and 380 deletions

View File

@@ -1,48 +0,0 @@
package org.cryptomator.ui.addvaultwizard;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
import javax.inject.Named;
@AddVaultWizardScoped
public class AddVaultGenericErrorController implements FxController {
private final Stage window;
private final ReadOnlyObjectProperty<Scene> previousScene;
private final BooleanBinding returnToPreviousSceneAllowed;
@Inject
AddVaultGenericErrorController(@AddVaultWizardWindow Stage window, @Named("genericErrorReturnScene") ObjectProperty<Scene> previousScene) {
this.window = window;
this.previousScene = previousScene;
this.returnToPreviousSceneAllowed = previousScene.isNotNull();
}
@FXML
public void back() {
assert previousScene.get() != null; // otherwise button should be disabled
window.setScene(previousScene.get());
}
@FXML
public void close(){
window.close();
}
/* Getter/Setter */
public BooleanBinding returnToPreviousSceneAllowedProperty() {
return returnToPreviousSceneAllowed;
}
public boolean isReturnToPreviousSceneAllowed() {
return returnToPreviousSceneAllowed.get();
}
}

View File

@@ -21,7 +21,6 @@ import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.NewPasswordController;
import org.cryptomator.ui.common.PasswordStrengthUtil;
import org.cryptomator.ui.common.StackTraceController;
import org.cryptomator.ui.mainwindow.MainWindow;
import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;
@@ -62,20 +61,6 @@ public abstract class AddVaultModule {
return stage;
}
@Provides
@Named("genericErrorCause")
@AddVaultWizardScoped
static ObjectProperty<Throwable> provideGenericErrorCause() {
return new SimpleObjectProperty<>();
}
@Provides
@Named("genericErrorReturnScene")
@AddVaultWizardScoped
static ObjectProperty<Scene> provideGenericErrorReturnScene() {
return new SimpleObjectProperty<>();
}
@Provides
@AddVaultWizardScoped
static ObjectProperty<Path> provideVaultPath() {
@@ -118,14 +103,7 @@ public abstract class AddVaultModule {
static Scene provideChooseExistingVaultScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_EXISTING.getRessourcePathString());
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_GENERIC_ERROR)
@AddVaultWizardScoped
static Scene provideGenericErrorScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_GENERIC_ERROR.getRessourcePathString());
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_NEW_NAME)
@AddVaultWizardScoped
@@ -211,16 +189,5 @@ public abstract class AddVaultModule {
@IntoMap
@FxControllerKey(AddVaultSuccessController.class)
abstract FxController bindAddVaultSuccessController(AddVaultSuccessController controller);
@Binds
@IntoMap
@FxControllerKey(AddVaultGenericErrorController.class)
abstract FxController bindAddVaultGenericErrorController(AddVaultGenericErrorController controller);
@Provides
@IntoMap
@FxControllerKey(StackTraceController.class)
static FxController provideStackTraceController(@Named("genericErrorCause") ObjectProperty<Throwable> errorCause) {
return new StackTraceController(errorCause.get());
}
}

View File

@@ -8,6 +8,7 @@ import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -29,20 +30,18 @@ public class ChooseExistingVaultController implements FxController {
private final Stage window;
private final Lazy<Scene> welcomeScene;
private final Lazy<Scene> successScene;
private final Lazy<Scene> genericErrorScene;
private final ObjectProperty<Throwable> genericErrorCause;
private final ErrorComponent.Builder errorComponent;
private final ObjectProperty<Path> vaultPath;
private final ObjectProperty<Vault> vault;
private final VaultListManager vaultListManager;
private final ResourceBundle resourceBundle;
@Inject
ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy<Scene> welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.ADDVAULT_GENERIC_ERROR) Lazy<Scene> genericErrorScene, @Named("genericErrorCause") ObjectProperty<Throwable> genericErrorCause, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, VaultListManager vaultListManager, ResourceBundle resourceBundle) {
ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy<Scene> welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ErrorComponent.Builder errorComponent, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, VaultListManager vaultListManager, ResourceBundle resourceBundle) {
this.window = window;
this.welcomeScene = welcomeScene;
this.successScene = successScene;
this.genericErrorScene = genericErrorScene;
this.genericErrorCause = genericErrorCause;
this.errorComponent = errorComponent;
this.vaultPath = vaultPath;
this.vault = vault;
this.vaultListManager = vaultListManager;
@@ -68,8 +67,7 @@ public class ChooseExistingVaultController implements FxController {
window.setScene(successScene.get());
} catch (NoSuchFileException e) {
LOG.error("Failed to open existing vault.", e);
genericErrorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
}
}

View File

@@ -16,6 +16,7 @@ import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -41,8 +42,7 @@ public class CreateNewVaultLocationController implements FxController {
private final Stage window;
private final Lazy<Scene> chooseNameScene;
private final Lazy<Scene> choosePasswordScene;
private final Lazy<Scene> genericErrorScene;
private final ObjectProperty<Throwable> genericErrorCause;
private final ErrorComponent.Builder errorComponent;
private final LocationPresets locationPresets;
private final ObjectProperty<Path> vaultPath;
private final StringProperty vaultName;
@@ -61,12 +61,11 @@ public class CreateNewVaultLocationController implements FxController {
public RadioButton customRadioButton;
@Inject
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, @FxmlScene(FxmlFile.ADDVAULT_GENERIC_ERROR) Lazy<Scene> genericErrorScene, @Named("genericErrorCause") ObjectProperty<Throwable> genericErrorCause, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, ErrorComponent.Builder errorComponent, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
this.window = window;
this.chooseNameScene = chooseNameScene;
this.choosePasswordScene = choosePasswordScene;
this.genericErrorScene = genericErrorScene;
this.genericErrorCause = genericErrorCause;
this.errorComponent = errorComponent;
this.locationPresets = locationPresets;
this.vaultPath = vaultPath;
this.vaultName = vaultName;
@@ -128,8 +127,7 @@ public class CreateNewVaultLocationController implements FxController {
warningText.set(resourceBundle.getString("addvaultwizard.new.fileAlreadyExists"));
} catch (IOException e) {
LOG.error("Failed to create and delete directory at chosen vault path.", e);
genericErrorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
}

View File

@@ -18,6 +18,7 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -53,9 +54,7 @@ public class CreateNewVaultPasswordController implements FxController {
private final Lazy<Scene> chooseLocationScene;
private final Lazy<Scene> recoveryKeyScene;
private final Lazy<Scene> successScene;
private final Lazy<Scene> genericErrorScene;
private final ObjectProperty<Throwable> genericErrorCause;
private final ObjectProperty<Scene> genericErrorReturnScene;
private final ErrorComponent.Builder errorComponent;
private final ExecutorService executor;
private final RecoveryKeyFactory recoveryKeyFactory;
private final StringProperty vaultNameProperty;
@@ -75,14 +74,12 @@ public class CreateNewVaultPasswordController implements FxController {
public Toggle skipRecoveryKey;
@Inject
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.ADDVAULT_GENERIC_ERROR) Lazy<Scene> genericErrorScene, @Named("genericErrorCause") ObjectProperty<Throwable> genericErrorCause, @Named("genericErrorReturnScene") ObjectProperty<Scene> genericErrorReturnScene, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, @Named("newPassword") ObjectProperty<CharSequence> password, ReadmeGenerator readmeGenerator) {
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ErrorComponent.Builder errorComponent, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, @Named("newPassword") ObjectProperty<CharSequence> password, ReadmeGenerator readmeGenerator) {
this.window = window;
this.chooseLocationScene = chooseLocationScene;
this.recoveryKeyScene = recoveryKeyScene;
this.successScene = successScene;
this.genericErrorScene = genericErrorScene;
this.genericErrorCause = genericErrorCause;
this.genericErrorReturnScene = genericErrorReturnScene;
this.errorComponent = errorComponent;
this.executor = executor;
this.recoveryKeyFactory = recoveryKeyFactory;
this.vaultNameProperty = vaultName;
@@ -117,9 +114,7 @@ public class CreateNewVaultPasswordController implements FxController {
Files.createDirectory(pathToVault);
} catch (IOException e) {
LOG.error("Failed to create vault directory.", e);
genericErrorReturnScene.set(window.getScene());
genericErrorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
return;
}
@@ -144,9 +139,7 @@ public class CreateNewVaultPasswordController implements FxController {
window.setScene(recoveryKeyScene.get());
}).onError(IOException.class, e -> {
LOG.error("Failed to initialize vault.", e);
genericErrorReturnScene.set(window.getScene());
genericErrorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}).andFinally(() -> {
processing.set(false);
}).runOnce(executor);
@@ -162,9 +155,7 @@ public class CreateNewVaultPasswordController implements FxController {
window.setScene(successScene.get());
}).onError(IOException.class, e -> {
LOG.error("Failed to initialize vault.", e);
genericErrorReturnScene.set(window.getScene());
genericErrorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}).andFinally(() -> {
processing.set(false);
}).runOnce(executor);

View File

@@ -0,0 +1,40 @@
package org.cryptomator.ui.common;
import dagger.BindsInstance;
import dagger.Subcomponent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javax.annotation.Nullable;
@Subcomponent(modules = {ErrorModule.class})
public interface ErrorComponent {
Stage window();
@FxmlScene(FxmlFile.ERROR)
Scene scene();
default void showErrorScene() {
Stage stage = window();
stage.setScene(scene());
stage.show();
}
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder cause(Throwable cause);
@BindsInstance
Builder window(Stage window);
@BindsInstance
Builder returnToScene(@Nullable Scene previousScene);
ErrorComponent build();
}
}

View File

@@ -0,0 +1,45 @@
package org.cryptomator.ui.common;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
public class ErrorController implements FxController {
private final String stackTrace;
private final Scene previousScene;
private final Stage window;
@Inject
ErrorController(@Named("stackTrace") String stackTrace, @Nullable Scene previousScene, Stage window) {
this.stackTrace = stackTrace;
this.previousScene = previousScene;
this.window = window;
}
@FXML
public void back() {
if (previousScene != null) {
window.setScene(previousScene);
}
}
@FXML
public void close() {
window.close();
}
/* Getter/Setter */
public boolean isPreviousScenePresent() {
return previousScene != null;
}
public String getStackTrace() {
return stackTrace;
}
}

View File

@@ -0,0 +1,45 @@
package org.cryptomator.ui.common;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import javafx.scene.Scene;
import javax.inject.Named;
import javax.inject.Provider;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.ResourceBundle;
@Module
abstract class ErrorModule {
@Provides
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@Named("stackTrace")
static String provideStackTrace(Throwable cause) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
cause.printStackTrace(new PrintStream(baos));
return baos.toString(StandardCharsets.UTF_8);
}
@Binds
@IntoMap
@FxControllerKey(ErrorController.class)
abstract FxController bindErrorController(ErrorController controller);
@Provides
@FxmlScene(FxmlFile.ERROR)
static Scene provideErrorScene(FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ERROR.getRessourcePathString());
}
}

View File

@@ -1,6 +1,5 @@
package org.cryptomator.ui.common;
import com.google.common.base.Splitter;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
@@ -9,7 +8,6 @@ import javax.inject.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.function.Function;
@@ -65,8 +63,9 @@ public class FXMLLoaderFactory {
throw new UncheckedIOException("Failed to load " + fxmlResourceName, e);
}
Parent root = loader.getRoot();
List<String> addtionalStyleSheets = Splitter.on(',').omitEmptyStrings().splitToList(resourceBundle.getString("additionalStyleSheets"));
addtionalStyleSheets.forEach(styleSheet -> root.getStylesheets().add("/css/" + styleSheet));
// TODO: discuss if we can remove language-specific stylesheets
// List<String> addtionalStyleSheets = Splitter.on(',').omitEmptyStrings().splitToList(resourceBundle.getString("additionalStyleSheets"));
// addtionalStyleSheets.forEach(styleSheet -> root.getStylesheets().add("/css/" + styleSheet));
return sceneFactory.apply(root);
}

View File

@@ -2,7 +2,6 @@ package org.cryptomator.ui.common;
public enum FxmlFile {
ADDVAULT_EXISTING("/fxml/addvault_existing.fxml"), //
ADDVAULT_GENERIC_ERROR("/fxml/addvault_generic_error.fxml"),
ADDVAULT_NEW_NAME("/fxml/addvault_new_name.fxml"), //
ADDVAULT_NEW_LOCATION("/fxml/addvault_new_location.fxml"), //
ADDVAULT_NEW_PASSWORD("/fxml/addvault_new_password.fxml"), //
@@ -10,10 +9,10 @@ public enum FxmlFile {
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
ERROR("/fxml/error.fxml"), //
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
MAIN_WINDOW("/fxml/main_window.fxml"), //
MIGRATION_CAPABILITY_ERROR("/fxml/migration_capability_error.fxml"), //
MIGRATION_GENERIC_ERROR("/fxml/migration_generic_error.fxml"), //
MIGRATION_RUN("/fxml/migration_run.fxml"), //
MIGRATION_START("/fxml/migration_start.fxml"), //
MIGRATION_SUCCESS("/fxml/migration_success.fxml"), //
@@ -25,7 +24,6 @@ public enum FxmlFile {
RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
REMOVE_VAULT("/fxml/remove_vault.fxml"), //
UNLOCK("/fxml/unlock.fxml"),
UNLOCK_GENERIC_ERROR("/fxml/unlock_generic_error.fxml"), //
UNLOCK_INVALID_MOUNT_POINT("/fxml/unlock_invalid_mount_point.fxml"), //
UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //
VAULT_OPTIONS("/fxml/vault_options.fxml"), //

View File

@@ -1,28 +0,0 @@
package org.cryptomator.ui.common;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
public class StackTraceController implements FxController {
private final String stackTrace;
public StackTraceController(Throwable cause) {
this.stackTrace = provideStackTrace(cause);
}
private static String provideStackTrace(Throwable cause) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
cause.printStackTrace(new PrintStream(baos));
return baos.toString(StandardCharsets.UTF_8);
}
/* Getter/Setter */
public String getStackTrace() {
return stackTrace;
}
}

View File

@@ -14,6 +14,7 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.image.Image;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent;
import org.cryptomator.ui.quit.QuitComponent;
@@ -26,7 +27,7 @@ import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.List;
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, QuitComponent.class})
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, QuitComponent.class, ErrorComponent.class})
abstract class FxApplicationModule {
@Provides

View File

@@ -1,29 +0,0 @@
package org.cryptomator.ui.migration;
import dagger.Lazy;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Inject;
@MigrationScoped
public class MigrationGenericErrorController implements FxController {
private final Stage window;
private final Lazy<Scene> startScene;
@Inject
MigrationGenericErrorController(@MigrationWindow Stage window, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene) {
this.window = window;
this.startScene = startScene;
}
@FXML
public void back() {
window.setScene(startScene.get());
}
}

View File

@@ -17,7 +17,6 @@ import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StackTraceController;
import org.cryptomator.ui.mainwindow.MainWindow;
import javax.inject.Named;
@@ -48,14 +47,7 @@ abstract class MigrationModule {
stage.getIcons().addAll(windowIcons);
return stage;
}
@Provides
@Named("genericErrorCause")
@MigrationScoped
static ObjectProperty<Throwable> provideGenericErrorCause() {
return new SimpleObjectProperty<>();
}
@Provides
@Named("capabilityErrorCause")
@MigrationScoped
@@ -91,14 +83,6 @@ abstract class MigrationModule {
return fxmlLoaders.createScene("/fxml/migration_capability_error.fxml");
}
@Provides
@FxmlScene(FxmlFile.MIGRATION_GENERIC_ERROR)
@MigrationScoped
static Scene provideMigrationGenericErrorScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_generic_error.fxml");
}
// ------------------
@Binds
@@ -120,17 +104,5 @@ abstract class MigrationModule {
@IntoMap
@FxControllerKey(MigrationCapabilityErrorController.class)
abstract FxController bindMigrationCapabilityErrorController(MigrationCapabilityErrorController controller);
@Binds
@IntoMap
@FxControllerKey(MigrationGenericErrorController.class)
abstract FxController bindMigrationGenericErrorController(MigrationGenericErrorController controller);
@Provides
@IntoMap
@FxControllerKey(StackTraceController.class)
static FxController provideStackTraceController(@Named("genericErrorCause") ObjectProperty<Throwable> errorCause) {
return new StackTraceController(errorCause.get());
}
}

View File

@@ -23,6 +23,7 @@ import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.keychain.KeychainAccess;
import org.cryptomator.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -54,31 +55,29 @@ public class MigrationRunController implements FxController {
private final ScheduledExecutorService scheduler;
private final Optional<KeychainAccess> keychainAccess;
private final ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability;
private final ObjectProperty<Throwable> errorCause;
private final ErrorComponent.Builder errorComponent;
private final Lazy<Scene> startScene;
private final Lazy<Scene> successScene;
private final ObjectBinding<ContentDisplay> migrateButtonContentDisplay;
private final Lazy<Scene> capabilityErrorScene;
private final Lazy<Scene> genericErrorScene;
private final BooleanProperty migrationButtonDisabled;
private final DoubleProperty migrationProgress;
private volatile double volatileMigrationProgress = -1.0;
public NiceSecurePasswordField passwordField;
@Inject
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, Optional<KeychainAccess> keychainAccess, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @Named("genericErrorCause") ObjectProperty<Throwable> errorCause, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, @FxmlScene(FxmlFile.MIGRATION_GENERIC_ERROR) Lazy<Scene> genericErrorScene) {
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, Optional<KeychainAccess> keychainAccess, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, ErrorComponent.Builder errorComponent) {
this.window = window;
this.vault = vault;
this.executor = executor;
this.scheduler = scheduler;
this.keychainAccess = keychainAccess;
this.missingCapability = missingCapability;
this.errorCause = errorCause;
this.errorComponent = errorComponent;
this.startScene = startScene;
this.successScene = successScene;
this.migrateButtonContentDisplay = Bindings.createObjectBinding(this::getMigrateButtonContentDisplay, vault.stateProperty());
this.capabilityErrorScene = capabilityErrorScene;
this.genericErrorScene = genericErrorScene;
this.migrationButtonDisabled = new SimpleBooleanProperty();
this.migrationProgress = new SimpleDoubleProperty(volatileMigrationProgress);
}
@@ -132,8 +131,7 @@ public class MigrationRunController implements FxController {
}).onError(Exception.class, e -> { // including RuntimeExceptions
LOG.error("Migration failed for technical reasons.", e);
vault.setState(VaultState.NEEDS_MIGRATION);
errorCause.set(e);
window.setScene(genericErrorScene.get());
errorComponent.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
}).andFinally(() -> {
progressSyncTask.cancel(true);
}).runOnce(executor);

View File

@@ -19,6 +19,7 @@ import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.keychain.KeychainAccess;
import org.cryptomator.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -49,15 +50,14 @@ public class UnlockController implements FxController {
private final VaultService vaultService;
private final Lazy<Scene> successScene;
private final Lazy<Scene> invalidMountPointScene;
private final Lazy<Scene> genericErrorScene;
private final ObjectProperty<Throwable> genericErrorCause;
private final ErrorComponent.Builder errorComponent;
private final ForgetPasswordComponent.Builder forgetPassword;
private final BooleanProperty unlockButtonDisabled;
public NiceSecurePasswordField passwordField;
public CheckBox savePassword;
@Inject
public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, @FxmlScene(FxmlFile.UNLOCK_GENERIC_ERROR) Lazy<Scene> genericErrorScene, @Named("genericErrorCause") ObjectProperty<Throwable> genericErrorCause, ForgetPasswordComponent.Builder forgetPassword) {
public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent, ForgetPasswordComponent.Builder forgetPassword) {
this.window = window;
this.vault = vault;
this.executor = executor;
@@ -66,8 +66,7 @@ public class UnlockController implements FxController {
this.vaultService = vaultService;
this.successScene = successScene;
this.invalidMountPointScene = invalidMountPointScene;
this.genericErrorScene = genericErrorScene;
this.genericErrorCause = genericErrorCause;
this.errorComponent = errorComponent;
this.forgetPassword = forgetPassword;
this.unlockButtonDisabled = new SimpleBooleanProperty();
}
@@ -116,8 +115,7 @@ public class UnlockController implements FxController {
window.setScene(invalidMountPointScene.get());
} else {
LOG.error("Unlock failed for technical reasons.", task.getException());
genericErrorCause.set(task.getException());
window.setScene(genericErrorScene.get());
errorComponent.cause(task.getException()).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
});
executor.execute(task);

View File

@@ -1,29 +0,0 @@
package org.cryptomator.ui.unlock;
import dagger.Lazy;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Inject;
@UnlockScoped
public class UnlockGenericErrorController implements FxController {
private final Stage window;
private final Lazy<Scene> unlockScene;
@Inject
UnlockGenericErrorController(@UnlockWindow Stage window, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene) {
this.window = window;
this.unlockScene = unlockScene;
}
@FXML
public void back() {
window.setScene(unlockScene.get());
}
}

View File

@@ -4,8 +4,6 @@ import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Modality;
@@ -16,7 +14,6 @@ import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StackTraceController;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import javax.inject.Named;
@@ -47,13 +44,6 @@ abstract class UnlockModule {
return stage;
}
@Provides
@Named("genericErrorCause")
@UnlockScoped
static ObjectProperty<Throwable> provideGenericErrorCause() {
return new SimpleObjectProperty<>();
}
@Provides
@FxmlScene(FxmlFile.UNLOCK)
@UnlockScoped
@@ -75,15 +65,6 @@ abstract class UnlockModule {
return fxmlLoaders.createScene("/fxml/unlock_invalid_mount_point.fxml");
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_GENERIC_ERROR)
@UnlockScoped
static Scene provideGenericErrorScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock_generic_error.fxml");
}
// ------------------
@Binds
@@ -101,17 +82,4 @@ abstract class UnlockModule {
@FxControllerKey(UnlockInvalidMountPointController.class)
abstract FxController bindUnlockInvalidMountPointController(UnlockInvalidMountPointController controller);
@Binds
@IntoMap
@FxControllerKey(UnlockGenericErrorController.class)
abstract FxController bindUnlockGenericErrorController(UnlockGenericErrorController controller);
@Provides
@IntoMap
@FxControllerKey(StackTraceController.class)
static FxController provideStackTraceController(@Named("genericErrorCause") ObjectProperty<Throwable> errorCause) {
return new StackTraceController(errorCause.get());
}
}

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.addvaultwizard.AddVaultGenericErrorController"
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>
<children>
<fx:include source="/fxml/stacktrace.fxml" VBox.vgrow="ALWAYS"/>
<ButtonBar buttonMinWidth="120" buttonOrder="B+C">
<buttons>
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" onAction="#back" visible="${controller.returnToPreviousSceneAllowed}"/>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" onAction="#close"/>
</buttons>
</ButtonBar>
</children>
</VBox>

View File

@@ -1,17 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.common.StackTraceController"
minWidth="300"
spacing="12">
fx:controller="org.cryptomator.ui.common.ErrorController"
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>
<children>
<HBox spacing="12" VBox.vgrow="NEVER">
<StackPane alignment="CENTER" HBox.hgrow="NEVER">
@@ -25,5 +33,12 @@
</HBox>
<TextArea VBox.vgrow="ALWAYS" text="${controller.stackTrace}" prefRowCount="5" editable="false"/>
<ButtonBar buttonMinWidth="120" buttonOrder="B+C">
<buttons>
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" onAction="#back" visible="${controller.previousScenePresent}"/>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" onAction="#close" />
</buttons>
</ButtonBar>
</children>
</VBox>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.Region?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.migration.MigrationGenericErrorController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<fx:include source="/fxml/stacktrace.fxml"/>
<Region VBox.vgrow="ALWAYS"/>
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
<ButtonBar buttonMinWidth="120" buttonOrder="B+U">
<buttons>
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" cancelButton="true" onAction="#back"/>
<Region ButtonBar.buttonData="OTHER"/>
</buttons>
</ButtonBar>
</VBox>
</children>
</VBox>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.Region?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.unlock.UnlockGenericErrorController"
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<fx:include source="/fxml/stacktrace.fxml"/>
<Region VBox.vgrow="ALWAYS"/>
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
<ButtonBar buttonMinWidth="120" buttonOrder="B+U">
<buttons>
<Button text="%generic.button.back" ButtonBar.buttonData="BACK_PREVIOUS" cancelButton="true" onAction="#back"/>
<Region ButtonBar.buttonData="OTHER"/>
</buttons>
</ButtonBar>
</VBox>
</children>
</VBox>