diff --git a/app/src/main/java/io/xpipe/app/browser/action/BrowserAction.java b/app/src/main/java/io/xpipe/app/browser/action/BrowserAction.java index 0d2cce15..a024c04e 100644 --- a/app/src/main/java/io/xpipe/app/browser/action/BrowserAction.java +++ b/app/src/main/java/io/xpipe/app/browser/action/BrowserAction.java @@ -31,7 +31,7 @@ public interface BrowserAction { .orElseThrow(); } - default void init(OpenFileSystemModel model) {} + default void init(OpenFileSystemModel model) throws Exception {} default String getProFeatureId() { return null; diff --git a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java index c1bc113a..3bd6400a 100644 --- a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java +++ b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java @@ -239,7 +239,8 @@ public class AppSocketServer { } } catch (SocketException ex) { // Omit it, as this might happen often - ErrorEvent.fromThrowable(ex).omitted(true).build().handle(); + // This is expected if you kill a running xpipe CLI process + ErrorEvent.fromThrowable(ex).expected().omit().build().handle(); } catch (Throwable ex) { ErrorEvent.fromThrowable(ex).build().handle(); } finally { diff --git a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java index 16f9d109..208b637e 100644 --- a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java @@ -26,7 +26,7 @@ public interface ActionProvider { } } - default void init() {} + default void init() throws Exception {} default String getId() { return null; diff --git a/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java b/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java index 55c6813a..1380edf9 100644 --- a/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java +++ b/app/src/main/java/io/xpipe/app/issue/EventHandlerImpl.java @@ -39,8 +39,7 @@ public class EventHandlerImpl extends EventHandler { // Don't block shutdown if (OperationMode.isInShutdown()) { - SentryErrorHandler.getInstance().handle(ee); - handle(fromErrorEvent(ee)); + handleOnShutdown(ee); return; } @@ -51,6 +50,11 @@ public class EventHandlerImpl extends EventHandler { } } + private void handleOnShutdown(ErrorEvent ee) { + ErrorAction.ignore().handle(ee); + handle(fromErrorEvent(ee)); + } + @Override public void modify(ErrorEvent ee) { if (AppLogs.get() != null && AppLogs.get().getSessionLogsDirectory() != null) { diff --git a/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java index 81096d6f..46daeae2 100644 --- a/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java @@ -36,6 +36,7 @@ public class GuiErrorHandler extends GuiErrorHandlerBase implements ErrorHandler if (lex.isPresent()) { LicenseProvider.get().showLicenseAlert(lex.get()); event.setShouldSendDiagnostics(true); + event.clearAttachments(); ErrorAction.ignore().handle(event); } else { ErrorHandlerComp.showAndTryWait(event, true); diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java index a84a9beb..5e4104e0 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java @@ -141,7 +141,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue { } @Override - protected CommandBuilder toCommand(LaunchConfiguration configuration) { + protected CommandBuilder toCommand(LaunchConfiguration configuration) throws Exception { // A weird behavior in Windows Terminal causes the trailing // backslash of a filepath to escape the closing quote in the title argument // So just remove that slash @@ -894,6 +894,6 @@ public interface ExternalTerminalType extends PrefsChoiceValue { launch(configuration.getColoredTitle(), args); } - protected abstract CommandBuilder toCommand(LaunchConfiguration configuration); + protected abstract CommandBuilder toCommand(LaunchConfiguration configuration) throws Exception; } } diff --git a/app/src/main/java/io/xpipe/app/util/LocalShell.java b/app/src/main/java/io/xpipe/app/util/LocalShell.java index 048fea31..f97a315a 100644 --- a/app/src/main/java/io/xpipe/app/util/LocalShell.java +++ b/app/src/main/java/io/xpipe/app/util/LocalShell.java @@ -19,8 +19,9 @@ public class LocalShell { } public static ShellControl getLocalPowershell() throws Exception { - if (ShellDialects.isPowershell(getShell())) { - return local; + var s = getShell(); + if (ShellDialects.isPowershell(s)) { + return s; } if (localPowershell == null) { @@ -29,18 +30,18 @@ public class LocalShell { .subShell(ShellDialects.POWERSHELL) .start(); } - return localPowershell; + return localPowershell.start(); } public static boolean isLocalShellInitialized() { return local != null; } - public static ShellControl getShell() { + public static ShellControl getShell() throws Exception { if (local == null) { throw new IllegalStateException("Local shell not initialized yet"); } - return local; + return local.start(); } } diff --git a/app/src/main/java/io/xpipe/app/util/ScanAlert.java b/app/src/main/java/io/xpipe/app/util/ScanAlert.java index fe03a6e6..d6804e8d 100644 --- a/app/src/main/java/io/xpipe/app/util/ScanAlert.java +++ b/app/src/main/java/io/xpipe/app/util/ScanAlert.java @@ -133,7 +133,9 @@ public class ScanAlert { } }); } finally { - shellControl.close(); + if (shellControl != null) { + shellControl.close(); + } shellControl = null; } }); diff --git a/app/src/main/java/io/xpipe/app/util/ShellControlCache.java b/app/src/main/java/io/xpipe/app/util/ShellControlCache.java index fdd1d7a2..ee044a12 100644 --- a/app/src/main/java/io/xpipe/app/util/ShellControlCache.java +++ b/app/src/main/java/io/xpipe/app/util/ShellControlCache.java @@ -1,6 +1,7 @@ package io.xpipe.app.util; import io.xpipe.core.process.ShellControl; +import io.xpipe.core.util.FailableSupplier; import lombok.Getter; import java.util.HashMap; @@ -36,6 +37,12 @@ public class ShellControlCache { multiPurposeCache.computeIfAbsent(key, s -> value.get()); } + public void setIfAbsentFailable(String key, FailableSupplier value) throws Exception { + if (multiPurposeCache.get(key) == null) { + multiPurposeCache.put(key, value.get()); + } + } + public boolean isApplicationInPath(String app) { if (!installedApplications.containsKey(app)) { try { diff --git a/app/src/main/java/io/xpipe/app/util/ShellTemp.java b/app/src/main/java/io/xpipe/app/util/ShellTemp.java index 473868d4..92447ffe 100644 --- a/app/src/main/java/io/xpipe/app/util/ShellTemp.java +++ b/app/src/main/java/io/xpipe/app/util/ShellTemp.java @@ -1,5 +1,6 @@ package io.xpipe.app.util; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellControl; import io.xpipe.core.store.FileNames; @@ -35,12 +36,12 @@ public class ShellTemp { var systemTemp = proc.getOsType().getTempDirectory(proc); if (!d.directoryExists(proc, systemTemp).executeAndCheck() || !checkDirectoryPermissions(proc, systemTemp)) { - throw new IOException("No permissions to access %s".formatted(systemTemp)); + throw ErrorEvent.expected(new IOException("No permissions to access %s".formatted(systemTemp))); } var home = proc.getOsType().getHomeDirectory(proc); if (!d.directoryExists(proc, home).executeAndCheck() || !checkDirectoryPermissions(proc, home)) { - throw new IOException("No permissions to access %s".formatted(home)); + throw ErrorEvent.expected(new IOException("No permissions to access %s".formatted(home))); } // Always delete legacy directory and do not care whether it partially fails