From 6d2819bde77ea2f128c65251682b1fac69e7eda7 Mon Sep 17 00:00:00 2001 From: woodser Date: Wed, 26 Apr 2023 08:56:52 -0400 Subject: [PATCH] improve error handling show error popup on error initializing trade instruct to close monero-wallet-rpc on error opening wallets throw error if trade missing wallet on init or failure to sign payout tx --- .../main/java/haveno/core/trade/Trade.java | 30 ++++++++----------- .../java/haveno/core/trade/TradeManager.java | 3 +- .../core/xmr/wallet/XmrWalletService.java | 12 +++++--- .../haveno/desktop/main/MainViewModel.java | 9 ++++++ 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/haveno/core/trade/Trade.java b/core/src/main/java/haveno/core/trade/Trade.java index 1b8b8596..1e52aee9 100644 --- a/core/src/main/java/haveno/core/trade/Trade.java +++ b/core/src/main/java/haveno/core/trade/Trade.java @@ -329,14 +329,19 @@ public abstract class Trade implements Tradable, Model { @Setter private long takeOfferDate; + // Initialization + private static final int TOTAL_INIT_STEPS = 15; // total estimated steps + private int initStep = 0; + @Getter + private double initProgress = 0; + @Getter + @Setter + private Exception initError; + // Mutable private long amount; @Setter private long price; - private int initStep = 0; - private static final int TOTAL_INIT_STEPS = 15; // total estimated steps - @Getter - private double initProgress = 0; @Nullable @Getter private State state = State.PREPARATION; @@ -673,7 +678,7 @@ public abstract class Trade implements Tradable, Model { // sync wallet if applicable if (!isDepositRequested() || isPayoutUnlocked()) return; - if (!walletExists()) log.warn("Missing trade wallet for {} {}", getClass().getSimpleName(), getId()); + if (!walletExists()) throw new IllegalStateException("Missing trade wallet for " + getClass().getSimpleName() + " " + getId()); if (xmrWalletService.getConnectionsService().getConnection() == null || Boolean.FALSE.equals(xmrWalletService.getConnectionsService().isConnected())) return; updateSyncing(); } @@ -1006,18 +1011,9 @@ public abstract class Trade implements Tradable, Model { if (sign) { // sign tx - try { - MoneroMultisigSignResult result = wallet.signMultisigTxHex(payoutTxHex); - if (result.getSignedMultisigTxHex() == null) throw new RuntimeException("Error signing payout tx"); - payoutTxHex = result.getSignedMultisigTxHex(); - } catch (Exception e) { - if (getPayoutTxHex() != null) { - log.info("Reusing previous payout tx for {} {} because signing failed with error \"{}\"", getClass().getSimpleName(), getId(), e.getMessage()); // in case previous message with signed tx failed to send - payoutTxHex = getPayoutTxHex(); - } else { - throw e; - } - } + MoneroMultisigSignResult result = wallet.signMultisigTxHex(payoutTxHex); + if (result.getSignedMultisigTxHex() == null) throw new RuntimeException("Error signing payout tx"); + payoutTxHex = result.getSignedMultisigTxHex(); // describe result describedTxSet = wallet.describeMultisigTxSet(payoutTxHex); diff --git a/core/src/main/java/haveno/core/trade/TradeManager.java b/core/src/main/java/haveno/core/trade/TradeManager.java index aa6533c8..3766627d 100644 --- a/core/src/main/java/haveno/core/trade/TradeManager.java +++ b/core/src/main/java/haveno/core/trade/TradeManager.java @@ -427,8 +427,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi } } catch (Exception e) { log.warn("Error initializing {} {}: {}", trade.getClass().getSimpleName(), trade.getId(), e.getMessage()); - e.printStackTrace(); - trade.prependErrorMessage(e.getMessage()); + trade.setInitError(e); } }); }; diff --git a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java index 08c2a54f..a78bd489 100644 --- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java +++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java @@ -232,10 +232,14 @@ public class XmrWalletService { public MoneroWalletRpc openWallet(String walletName) { log.info("{}.openWallet({})", getClass().getSimpleName(), walletName); if (isShutDownStarted) throw new IllegalStateException("Cannot open wallet because shutting down"); - return openWalletRpc(new MoneroWalletConfig() - .setPath(walletName) - .setPassword(getWalletPassword()), - null); + try { + return openWalletRpc(new MoneroWalletConfig() + .setPath(walletName) + .setPassword(getWalletPassword()), + null); + } catch (MoneroError e) { + throw new IllegalStateException("Could not open wallet '" + walletName + "'. Please close Haveno, stop all monero-wallet-rpc processes, and restart Haveno."); + } } /** diff --git a/desktop/src/main/java/haveno/desktop/main/MainViewModel.java b/desktop/src/main/java/haveno/desktop/main/MainViewModel.java index 2fe8c9d0..78525f60 100644 --- a/desktop/src/main/java/haveno/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/MainViewModel.java @@ -220,6 +220,15 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener tradeManager.applyTradePeriodState(); tradeManager.getObservableList().forEach(trade -> { + + // check initialization error + if (trade.getInitError() != null) { + new Popup().warning("Error initializing trade" + " " + trade.getShortId() + "\n\n" + + trade.getInitError().getMessage()) + .show(); + } + + // check trade period Date maxTradePeriodDate = trade.getMaxTradePeriodDate(); String key; switch (trade.getPeriodState()) {