Browse Source

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.
renovate/lint-staged-8.x
Tom Kirkpatrick 6 years ago
parent
commit
0660801fb7
  1. 19
      app/containers/Root.js
  2. 19
      app/lib/zap/controller.js
  3. 8
      app/reducers/onboarding.js

19
app/containers/Root.js

@ -4,6 +4,9 @@ import { ConnectedRouter } from 'react-router-redux'
import { Switch, Route } from 'react-router' import { Switch, Route } from 'react-router'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { hot } from 'react-hot-loader' import { hot } from 'react-hot-loader'
import GlobalError from 'components/GlobalError'
import { clearError } from 'reducers/error'
import { import {
setConnectionType, setConnectionType,
@ -40,6 +43,7 @@ import App from './App'
import Activity from './Activity' import Activity from './Activity'
const mapDispatchToProps = { const mapDispatchToProps = {
clearError,
setConnectionType, setConnectionType,
setConnectionString, setConnectionString,
setConnectionHost, setConnectionHost,
@ -73,6 +77,7 @@ const mapStateToProps = state => ({
theme: state.settings.theme, theme: state.settings.theme,
balance: state.balance, balance: state.balance,
currentTicker: tickerSelectors.currentTicker(state), currentTicker: tickerSelectors.currentTicker(state),
error: state.error,
syncPercentage: lndSelectors.syncPercentage(state), syncPercentage: lndSelectors.syncPercentage(state),
passwordIsValid: onboardingSelectors.passwordIsValid(state), passwordIsValid: onboardingSelectors.passwordIsValid(state),
passwordMinCharsError: onboardingSelectors.passwordMinCharsError(state), passwordMinCharsError: onboardingSelectors.passwordMinCharsError(state),
@ -218,7 +223,16 @@ class Root extends Component {
} }
render() { 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) { if (!onboardingProps.onboarding.onboarded) {
return ( return (
@ -227,6 +241,7 @@ class Root extends Component {
theme={onboardingProps.theme} theme={onboardingProps.theme}
visible={!onboardingProps.onboarding.onboarding} visible={!onboardingProps.onboarding.onboarding}
/> />
<GlobalError error={error} clearError={clearError} />
<Onboarding {...onboardingProps} /> <Onboarding {...onboardingProps} />
<Syncing {...syncingProps} /> <Syncing {...syncingProps} />
</div> </div>
@ -267,6 +282,8 @@ class Root extends Component {
Root.propTypes = { Root.propTypes = {
balance: PropTypes.object.isRequired, balance: PropTypes.object.isRequired,
clearError: PropTypes.func.isRequired,
error: PropTypes.object.isRequired,
fetchTicker: PropTypes.func.isRequired, fetchTicker: PropTypes.func.isRequired,
currentTicker: PropTypes.object, currentTicker: PropTypes.object,
history: PropTypes.object.isRequired, history: PropTypes.object.isRequired,

19
app/lib/zap/controller.js

@ -187,6 +187,10 @@ class ZapController {
else if (e.code === 'LND_GRPC_MACAROON_ERROR') { else if (e.code === 'LND_GRPC_MACAROON_ERROR') {
errors.macaroon = e.message 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 // 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` // 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() 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. // Notify the app of errors.
this.sendMessage('startLndError', errors) this.sendMessage('startLndError', errors)
throw e throw e
@ -436,7 +435,15 @@ class ZapController {
*/ */
_registerIpcListeners() { _registerIpcListeners() {
ipcMain.on('startLnd', (event, options: onboardingOptions) => this.finishOnboarding(options)) 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()
})
)
} }
/** /**

8
app/reducers/onboarding.js

@ -2,6 +2,7 @@ import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import get from 'lodash.get' import get from 'lodash.get'
import { fetchInfo } from './info' import { fetchInfo } from './info'
import { setError } from './error'
// ------------------------------------ // ------------------------------------
// Constants // Constants
@ -292,14 +293,19 @@ export const startOnboarding = (event, lndConfig = {}) => dispatch => {
// Listener for errors connecting to LND gRPC // Listener for errors connecting to LND gRPC
export const startLndError = (event, errors) => (dispatch, getState) => { export const startLndError = (event, errors) => (dispatch, getState) => {
dispatch(setStartLndError(errors))
const connectionType = connectionTypeSelector(getState()) const connectionType = connectionTypeSelector(getState())
switch (connectionType) { switch (connectionType) {
case 'local':
dispatch(setError(errors))
dispatch({ type: CHANGE_STEP, step: 0.1 })
break
case 'custom': case 'custom':
dispatch(setStartLndError(errors))
dispatch({ type: CHANGE_STEP, step: 0.2 }) dispatch({ type: CHANGE_STEP, step: 0.2 })
break break
case 'btcpayserver': case 'btcpayserver':
dispatch(setStartLndError(errors))
dispatch({ type: CHANGE_STEP, step: 0.3 }) dispatch({ type: CHANGE_STEP, step: 0.3 })
break break
} }

Loading…
Cancel
Save