Skip to content

Commit

Permalink
Merge pull request #193 from lightninglabs/failure-reasons
Browse files Browse the repository at this point in the history
loop+history: display failure reason on History Page
  • Loading branch information
guggero committed Mar 2, 2021
2 parents 45d559e + bb40620 commit 1724184
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
19 changes: 18 additions & 1 deletion app/src/__tests__/components/history/HistoryRow.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import * as LOOP from 'types/generated/loop_pb';
import { renderWithProviders } from 'util/tests';
import { loopListSwaps } from 'util/tests/sampleData';
import { Swap } from 'store/models';
Expand All @@ -8,7 +9,7 @@ describe('HistoryRow component', () => {
let swap: Swap;

beforeEach(async () => {
swap = new Swap(loopListSwaps.swapsList[0]);
swap = new Swap(loopListSwaps.swapsList[1]);
});

const render = () => {
Expand All @@ -20,6 +21,22 @@ describe('HistoryRow component', () => {
expect(getByText(swap.stateLabel)).toBeInTheDocument();
});

it.each<[number, string]>([
[LOOP.FailureReason.FAILURE_REASON_NONE, 'Failed'],
[LOOP.FailureReason.FAILURE_REASON_OFFCHAIN, 'Off-chain Failure'],
[LOOP.FailureReason.FAILURE_REASON_TIMEOUT, 'On-chain Timeout'],
[LOOP.FailureReason.FAILURE_REASON_SWEEP_TIMEOUT, 'Sweep Timeout'],
[LOOP.FailureReason.FAILURE_REASON_INSUFFICIENT_VALUE, 'Insufficient Value'],
[LOOP.FailureReason.FAILURE_REASON_TEMPORARY, 'Temporary Failure'],
[LOOP.FailureReason.FAILURE_REASON_INCORRECT_AMOUNT, 'Incorrect Amount'],
])('should display correct dot icon for a "(%s) %s"', (reason, label) => {
swap.state = LOOP.SwapState.FAILED;
swap.failureReason = reason;

const { getByText } = render();
expect(getByText(label)).toBeInTheDocument();
});

it('should display the type', () => {
const { getByText } = render();
expect(getByText(swap.typeName)).toBeInTheDocument();
Expand Down
23 changes: 21 additions & 2 deletions app/src/components/history/HistoryRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { observer } from 'mobx-react-lite';
import { usePrefixedTranslation } from 'hooks';
import { useStore } from 'store';
import { Swap } from 'store/models';
import { Column, Row } from 'components/base';
import { Column, HelpCircle, Row } from 'components/base';
import SortableHeader from 'components/common/SortableHeader';
import Tip from 'components/common/Tip';
import Unit from 'components/common/Unit';
import SwapDot from 'components/loop/SwapDot';
import { styled } from 'components/theme';
Expand Down Expand Up @@ -110,13 +111,31 @@ interface Props {
}

const HistoryRow: React.FC<Props> = ({ swap, style }) => {
const { l } = usePrefixedTranslation('cmps.history.HistoryRow');
const { Row, Column, ActionColumn } = Styled;
return (
<Row style={style}>
<ActionColumn>
<SwapDot swap={swap} />
</ActionColumn>
<Column cols={3}>{swap.stateLabel}</Column>
<Column cols={3}>
{swap.stateLabel !== 'Failed' ? (
swap.stateLabel
) : (
<>
{swap.failureLabel}
<Tip
overlay={l(`failure-${swap.failureReason}`)}
capitalize={false}
maxWidth={300}
>
<span>
<HelpCircle />
</span>
</Tip>
</>
)}
</Column>
<Column>{swap.typeName}</Column>
<Column right>
<Unit sats={swap.amount} suffix={false} />
Expand Down
7 changes: 7 additions & 0 deletions app/src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
"cmps.history.HistoryRowHeader.type": "Type",
"cmps.history.HistoryRowHeader.created": "Created",
"cmps.history.HistoryRowHeader.updated": "Updated",
"cmps.history.HistoryRow.failure-0": "The swap has failed to complete successfully. Check the logs for additional information.",
"cmps.history.HistoryRow.failure-1": "Unable to find a route for one or both off chain payments that met the fee and timelock limits required.",
"cmps.history.HistoryRow.failure-2": "The on-chain HTLC did not confirm before its expiry, or it confirmed too late for us to reveal our preimage and claim.",
"cmps.history.HistoryRow.failure-3": "The on-chain HTLC wasn't swept before the server revoked the HTLC.",
"cmps.history.HistoryRow.failure-4": "The on-chain HTLC has a lower value than requested.",
"cmps.history.HistoryRow.failure-5": "The swap cannot continue due to an internal error. Manual intervention such as a restart is required.",
"cmps.history.HistoryRow.failure-6": "The amount extended by an external Loop In HTLC is insufficient.",
"cmps.loop.ChannelIcon.processing.in": "Loop In currently in progress",
"cmps.loop.ChannelIcon.processing.out": "Loop Out currently in progress",
"cmps.loop.ChannelIcon.processing.both": "Loop In and Loop Out currently in progress",
Expand Down
25 changes: 25 additions & 0 deletions app/src/store/models/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class Swap {
initiationTime = 0;
lastUpdateTime = 0;
state = 0;
failureReason = 0;

constructor(loopSwap: LOOP.SwapStatus.AsObject) {
makeAutoObservable(this, {}, { deep: false, autoBind: true });
Expand Down Expand Up @@ -81,6 +82,29 @@ export default class Swap {
return 'Unknown';
}

/**
* The numeric swap `failureReason` as a user friendly string
*/
get failureLabel() {
switch (this.failureReason) {
case LOOP.FailureReason.FAILURE_REASON_OFFCHAIN:
return 'Off-chain Failure';
case LOOP.FailureReason.FAILURE_REASON_TIMEOUT:
return 'On-chain Timeout';
case LOOP.FailureReason.FAILURE_REASON_SWEEP_TIMEOUT:
return 'Sweep Timeout';
case LOOP.FailureReason.FAILURE_REASON_INSUFFICIENT_VALUE:
return 'Insufficient Value';
case LOOP.FailureReason.FAILURE_REASON_TEMPORARY:
return 'Temporary Failure';
case LOOP.FailureReason.FAILURE_REASON_INCORRECT_AMOUNT:
return 'Incorrect Amount';
case LOOP.FailureReason.FAILURE_REASON_NONE:
default:
return 'Failed';
}
}

/** The date this swap was created as a JS Date object */
get createdOn() {
return new Date(this.initiationTime / 1000 / 1000);
Expand Down Expand Up @@ -112,6 +136,7 @@ export default class Swap {
this.initiationTime = loopSwap.initiationTime;
this.lastUpdateTime = loopSwap.lastUpdateTime;
this.state = loopSwap.state;
this.failureReason = loopSwap.failureReason;
}

/**
Expand Down

0 comments on commit 1724184

Please sign in to comment.