From 9ad55aa27e44b652c623d4a28d0242338893e61e Mon Sep 17 00:00:00 2001 From: crschnick Date: Thu, 4 Jun 2026 03:17:28 +0000 Subject: [PATCH] Improve error handling at various places --- .../file/BrowserFileListCompEntry.java | 2 +- .../app/browser/file/BrowserTransferComp.java | 4 +- .../browser/file/BrowserTransferModel.java | 52 ++++++++++--------- .../xpipe/app/core/window/AppWindowStyle.java | 2 +- .../io/xpipe/app/platform/PlatformState.java | 6 +-- .../java/io/xpipe/app/util/FileBridge.java | 8 +-- .../xpipe/app/util/RemoteDesktopWindow.java | 5 ++ 7 files changed, 44 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java index 6fbce30cb..70a4a81e0 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java @@ -216,7 +216,7 @@ public class BrowserFileListCompEntry { return null; } }) - .filter(path -> path != null) + .filter(path -> path != null && !path.toString().isEmpty()) .toList(); var target = item != null && item.getRawFileEntry().resolved().getKind() == FileKind.DIRECTORY ? item.getRawFileEntry().resolved() diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java index 7032ec2d8..2133085ad 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java @@ -95,14 +95,14 @@ public class BrowserTransferComp extends SimpleRegionBuilder { struc.setOnMouseClicked(e -> { if (e.getButton() == MouseButton.PRIMARY) { var open = !e.isShiftDown(); - ThreadHelper.runFailableAsync(() -> { + ThreadHelper.runAsync(() -> { model.transferToDownloads(open); }); e.consume(); } }); struc.setOnAction(e -> { - ThreadHelper.runFailableAsync(() -> { + ThreadHelper.runAsync(() -> { model.transferToDownloads(true); }); e.consume(); diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java index 9939fe723..0b7f76760 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java @@ -194,7 +194,7 @@ public class BrowserTransferModel { } } - public void transferToDownloads(boolean open) throws Exception { + public void transferToDownloads(boolean open) { List toMove; synchronized (items) { toMove = items.stream() @@ -206,32 +206,36 @@ public class BrowserTransferModel { items.removeAll(toMove); } - var files = toMove.stream().map(item -> item.getLocalFile()).toList(); - var downloads = getDownloadsTargetDirectory(); - Files.createDirectories(downloads); - Path firstToOpen = null; - for (Path file : files) { - if (!Files.exists(file)) { - continue; - } + try { + var files = toMove.stream().map(item -> item.getLocalFile()).toList(); + var downloads = getDownloadsTargetDirectory(); + Files.createDirectories(downloads); + Path firstToOpen = null; + for (Path file : files) { + if (!Files.exists(file)) { + continue; + } - var target = downloads.resolve(file.getFileName()); - // Prevent DirectoryNotEmptyException - if (Files.exists(target) && Files.isDirectory(target)) { - FileUtils.deleteDirectory(target.toFile()); - } - if (Files.isDirectory(file)) { - FileUtils.moveDirectory(file.toFile(), target.toFile()); - } else { - Files.move(file, target, StandardCopyOption.REPLACE_EXISTING); - } + var target = downloads.resolve(file.getFileName()); + // Prevent DirectoryNotEmptyException + if (Files.exists(target) && Files.isDirectory(target)) { + FileUtils.deleteDirectory(target.toFile()); + } + if (Files.isDirectory(file)) { + FileUtils.moveDirectory(file.toFile(), target.toFile()); + } else { + Files.move(file, target, StandardCopyOption.REPLACE_EXISTING); + } - if (firstToOpen == null) { - firstToOpen = target; + if (firstToOpen == null) { + firstToOpen = target; + } } - } - if (open && firstToOpen != null) { - DesktopHelper.browseFileInDirectory(firstToOpen); + if (open && firstToOpen != null) { + DesktopHelper.browseFileInDirectory(firstToOpen); + } + } catch (IOException e) { + ErrorEventFactory.fromThrowable(e).expected().handle(); } } diff --git a/app/src/main/java/io/xpipe/app/core/window/AppWindowStyle.java b/app/src/main/java/io/xpipe/app/core/window/AppWindowStyle.java index a04609d6f..1d1e21b5a 100644 --- a/app/src/main/java/io/xpipe/app/core/window/AppWindowStyle.java +++ b/app/src/main/java/io/xpipe/app/core/window/AppWindowStyle.java @@ -23,7 +23,7 @@ import java.util.List; public class AppWindowStyle { public static void setSceneFill(Scene scene) { - if (OsType.ofLocal() != OsType.LINUX) { + if (OsType.ofLocal() != OsType.LINUX || AppPrefs.get() == null) { scene.setFill(Color.TRANSPARENT); return; } diff --git a/app/src/main/java/io/xpipe/app/platform/PlatformState.java b/app/src/main/java/io/xpipe/app/platform/PlatformState.java index 74af4ecc4..baf4639f3 100644 --- a/app/src/main/java/io/xpipe/app/platform/PlatformState.java +++ b/app/src/main/java/io/xpipe/app/platform/PlatformState.java @@ -123,11 +123,11 @@ public enum PlatformState { // Catch more than just the headless exception in case the graphics environment initialization completely // fails - } catch (HeadlessException h) { - var msg = getErrorMessage(h.getMessage()); + } catch (HeadlessException | AWTError e) { + var msg = getErrorMessage(e.getMessage()); PlatformState.setCurrent(PlatformState.EXITED); expectedError = true; - lastError = new UnsupportedOperationException(msg, h); + lastError = new UnsupportedOperationException(msg, e); return; } catch (Throwable t) { PlatformState.setCurrent(PlatformState.EXITED); diff --git a/app/src/main/java/io/xpipe/app/util/FileBridge.java b/app/src/main/java/io/xpipe/app/util/FileBridge.java index e7b8002ab..94c43f6fa 100644 --- a/app/src/main/java/io/xpipe/app/util/FileBridge.java +++ b/app/src/main/java/io/xpipe/app/util/FileBridge.java @@ -56,7 +56,7 @@ public class FileBridge { } }); } catch (IOException e) { - ErrorEventFactory.fromThrowable(e).handle(); + ErrorEventFactory.fromThrowable(e).expected().handle(); } } @@ -168,7 +168,7 @@ public class FileBridge { input.onFinish(); } } catch (Exception ex) { - ErrorEventFactory.fromThrowable(ex).handle(); + ErrorEventFactory.fromThrowable(ex).expected().handle(); return; } ext.get().registerChange(); @@ -188,7 +188,7 @@ public class FileBridge { input.onFinish(); } } catch (Exception ex) { - ErrorEventFactory.fromThrowable(ex).handle(); + ErrorEventFactory.fromThrowable(ex).expected().handle(); return; } @@ -208,7 +208,7 @@ public class FileBridge { .build(); action.executeSync(); } catch (Exception ex) { - ErrorEventFactory.fromThrowable(ex).handle(); + ErrorEventFactory.fromThrowable(ex).expected().handle(); } } }); diff --git a/app/src/main/java/io/xpipe/app/util/RemoteDesktopWindow.java b/app/src/main/java/io/xpipe/app/util/RemoteDesktopWindow.java index 15164f897..845e8c7fe 100644 --- a/app/src/main/java/io/xpipe/app/util/RemoteDesktopWindow.java +++ b/app/src/main/java/io/xpipe/app/util/RemoteDesktopWindow.java @@ -1,6 +1,7 @@ package io.xpipe.app.util; import io.xpipe.app.core.*; +import io.xpipe.app.core.mode.AppOperationMode; import io.xpipe.app.core.window.AppMainWindow; import io.xpipe.app.core.window.AppModifiedStage; import io.xpipe.app.core.window.AppWindowStyle; @@ -307,6 +308,10 @@ public class RemoteDesktopWindow { } private void updateState() { + if (AppOperationMode.isInShutdown()) { + return; + } + model.clearDead(); DerivedObservableList.wrap(processes, true).setContent(model.getEntries()); selected.set(model.getSelected());