From 0660801fb792f7bdfa8cc285174175aec120b1dc Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Mon, 1 Oct 2018 10:46:58 +0200 Subject: [PATCH] fix(lnd): show error on problem connecting to lnd If there is a problem connecting to the Lightning interface on a local lnd instance, return the user to the onboarding screen and show the user the error message. Previously, the app would hang on an infinite loading screen. --- app/containers/Root.js | 19 ++++++++++++++++++- app/lib/zap/controller.js | 19 +++++++++++++------ app/reducers/onboarding.js | 8 +++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/app/containers/Root.js b/app/containers/Root.js index 7adf870d..4381ef97 100644 --- a/app/containers/Root.js +++ b/app/containers/Root.js @@ -4,6 +4,9 @@ import { ConnectedRouter } from 'react-router-redux' import { Switch, Route } from 'react-router' import PropTypes from 'prop-types' import { hot } from 'react-hot-loader' +import GlobalError from 'components/GlobalError' + +import { clearError } from 'reducers/error' import { setConnectionType, @@ -40,6 +43,7 @@ import App from './App' import Activity from './Activity' const mapDispatchToProps = { + clearError, setConnectionType, setConnectionString, setConnectionHost, @@ -73,6 +77,7 @@ const mapStateToProps = state => ({ theme: state.settings.theme, balance: state.balance, currentTicker: tickerSelectors.currentTicker(state), + error: state.error, syncPercentage: lndSelectors.syncPercentage(state), passwordIsValid: onboardingSelectors.passwordIsValid(state), passwordMinCharsError: onboardingSelectors.passwordMinCharsError(state), @@ -218,7 +223,16 @@ class Root extends Component { } render() { - const { balance, currentTicker, history, lnd, onboardingProps, syncingProps } = this.props + const { + balance, + clearError, + currentTicker, + error: { error }, + history, + lnd, + onboardingProps, + syncingProps + } = this.props if (!onboardingProps.onboarding.onboarded) { return ( @@ -227,6 +241,7 @@ class Root extends Component { theme={onboardingProps.theme} visible={!onboardingProps.onboarding.onboarding} /> + @@ -267,6 +282,8 @@ class Root extends Component { Root.propTypes = { balance: PropTypes.object.isRequired, + clearError: PropTypes.func.isRequired, + error: PropTypes.object.isRequired, fetchTicker: PropTypes.func.isRequired, currentTicker: PropTypes.object, history: PropTypes.object.isRequired, diff --git a/app/lib/zap/controller.js b/app/lib/zap/controller.js index c698ca7d..f1bb0497 100644 --- a/app/lib/zap/controller.js +++ b/app/lib/zap/controller.js @@ -187,6 +187,10 @@ class ZapController { else if (e.code === 'LND_GRPC_MACAROON_ERROR') { errors.macaroon = e.message } + // Other error codes such as UNAVAILABLE most likely indicate that there is a problem with the host. + else { + errors.host = `Unable to connect to host: ${e.details || e.message}` + } // The `startLightningWallet` call attempts to call the `getInfo` method on the Lightning service in order to // verify that it is accessible. If it is not, an error 12 is throw whcih is the gRPC code for `UNIMPLEMENTED` @@ -196,11 +200,6 @@ class ZapController { return this.startWalletUnlocker() } - // Other error codes such as UNAVAILABLE most likely indicate that there is a problem with the host. - else { - errors.host = `Unable to connect to host: ${e.details || e.message}` - } - // Notify the app of errors. this.sendMessage('startLndError', errors) throw e @@ -436,7 +435,15 @@ class ZapController { */ _registerIpcListeners() { ipcMain.on('startLnd', (event, options: onboardingOptions) => this.finishOnboarding(options)) - ipcMain.on('startLightningWallet', () => this.startLightningWallet()) + ipcMain.on('startLightningWallet', () => + this.startLightningWallet().catch(e => { + // Notify the app of errors. + this.sendMessage('startLndError', e.message) + + // Return back to the start of the onboarding process. + return this.startOnboarding() + }) + ) } /** diff --git a/app/reducers/onboarding.js b/app/reducers/onboarding.js index b42dfa4e..10f51343 100644 --- a/app/reducers/onboarding.js +++ b/app/reducers/onboarding.js @@ -2,6 +2,7 @@ import { createSelector } from 'reselect' import { ipcRenderer } from 'electron' import get from 'lodash.get' import { fetchInfo } from './info' +import { setError } from './error' // ------------------------------------ // Constants @@ -292,14 +293,19 @@ export const startOnboarding = (event, lndConfig = {}) => dispatch => { // Listener for errors connecting to LND gRPC export const startLndError = (event, errors) => (dispatch, getState) => { - dispatch(setStartLndError(errors)) const connectionType = connectionTypeSelector(getState()) switch (connectionType) { + case 'local': + dispatch(setError(errors)) + dispatch({ type: CHANGE_STEP, step: 0.1 }) + break case 'custom': + dispatch(setStartLndError(errors)) dispatch({ type: CHANGE_STEP, step: 0.2 }) break case 'btcpayserver': + dispatch(setStartLndError(errors)) dispatch({ type: CHANGE_STEP, step: 0.3 }) break }