Skip to content

Commit

Permalink
Merge pull request #3800 from LiskHQ/3783-tx-broadcast-fail
Browse files Browse the repository at this point in the history
Handle transaction nonce fail - Closes #3783
  • Loading branch information
ManuGowda authored Sep 20, 2021
2 parents e0dd4d9 + 223a767 commit 02904b7
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 38 deletions.
76 changes: 45 additions & 31 deletions src/components/shared/transactionResult/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* eslint-disable complexity */
import React from 'react';
import { useSelector } from 'react-redux';
import { getErrorReportMailto, isEmpty } from '@utils/helpers';
import { transactionToJSON } from '@utils/transaction';
import { TertiaryButton } from '@toolbox/buttons';
import Illustration from '@toolbox/illustration';
import { selectActiveTokenNetwork } from '@store/selectors';
import styles from './transactionResult.css';

const illustrations = {
Expand Down Expand Up @@ -52,36 +54,48 @@ export const getBroadcastStatus = (transactions, isHardwareWalletError) => {

export const TransactionResult = ({
title, message, t, status, children, illustration, className,
}) => (
<div className={`${styles.wrapper} ${className}`}>
{
typeof illustration === 'string'
? <Illustration name={illustrations[illustration][status.code]} />
: React.cloneElement(illustration)
}
<h1 className="result-box-header">{title}</h1>
<p className="transaction-status body-message">{message}</p>
{children}
{
errorTypes.includes(status.code)
? (
<>
<p>{t('Does the problem still persist?')}</p>
<a
className="report-error-link"
href={getErrorReportMailto(status.message)}
target="_top"
rel="noopener noreferrer"
>
<TertiaryButton>
{t('Report the error via email')}
</TertiaryButton>
</a>
</>
)
: null
}
</div>
);
}) => {
const network = useSelector(selectActiveTokenNetwork);

return (
<div className={`${styles.wrapper} ${className}`}>
{
typeof illustration === 'string'
? <Illustration name={illustrations[illustration][status.code]} />
: React.cloneElement(illustration)
}
<h1 className="result-box-header">{title}</h1>
<p className="transaction-status body-message">{message}</p>
{children}
{
errorTypes.includes(status.code)
? (
<>
<p>{t('Does the problem still persist?')}</p>
<a
className="report-error-link"
href={getErrorReportMailto(
{
error: status.message,
errorMessage: message,
networkIdentifier: network.networkIdentifier,
serviceUrl: network.serviceUrl,
liskCoreVersion: network.networkVersion,
},
)}
target="_top"
rel="noopener noreferrer"
>
<TertiaryButton>
{t('Report the error via email')}
</TertiaryButton>
</a>
</>
)
: null
}
</div>
);
};

export default TransactionResult;
4 changes: 2 additions & 2 deletions src/store/actions/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const resetTransactionResult = () => ({
* Calls transactionAPI.create for create the tx object that will broadcast
* @param {Object} data
* @param {String} data.recipientAddress
* @param {Number} data.amount - In raw format (satoshis, beddows)
* @param {Number} data.amount - In raw format (satoshi, beddows)
* @param {Number} data.fee - In raw format, used for updating the TX List.
* @param {Number} data.dynamicFeePerByte - In raw format, used for creating BTC transaction.
* @param {Number} data.reference - Data field for LSK transactions
Expand Down Expand Up @@ -133,7 +133,7 @@ export const transactionCreated = data => async (dispatch, getState) => {
* Calls transactionAPI.broadcast function for put the tx object (signed) into the network
* @param {Object} transaction
* @param {String} transaction.recipientAddress
* @param {Number} transaction.amount - In raw format (satoshis, beddows)
* @param {Number} transaction.amount - In raw format (satoshi, beddows)
* @param {Number} transaction.fee - In raw format, used for updating the TX List.
* @param {Number} transaction.dynamicFeePerByte - In raw format, used for creating BTC transaction.
* @param {Number} transaction.reference - Data field for LSK transactions
Expand Down
2 changes: 2 additions & 0 deletions src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const selectBookmark = (state, address) =>
const selectSettings = state => state.settings;
const selectServiceUrl = state => state.network.networks?.LSK?.serviceUrl;
const selectCurrentBlockHeight = state => state.blocks.latestBlocks[0]?.height || 0;
const selectActiveTokenNetwork = state => state.network.networks[state.settings.token.active];

export {
selectBookmark,
Expand All @@ -30,4 +31,5 @@ export {
selectAccountBalance,
selectServiceUrl,
selectCurrentBlockHeight,
selectActiveTokenNetwork,
};
4 changes: 3 additions & 1 deletion src/utils/api/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ const http = ({
},
...restOptions,
})
.then((response) => {
.then(async (response) => {
if (!response.ok) {
const { message } = await response.json();
const error = Error(response.statusText);
error.code = response.status;
error.message = message;
throw error;
}
return response.json();
Expand Down
6 changes: 4 additions & 2 deletions src/utils/api/http.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ describe('HTTP', () => {

it('should throw error when response.ok is false', async () => {
const statusText = 'Response.ok is false';
const message = 'api error';
global.fetch = jest.fn(() => Promise.resolve({
ok: false,
status: 200,
status: 400,
statusText,
json: () => Promise.resolve({ message }),
}));
await expect(http(data)).rejects.toEqual(Error(statusText));
await expect(http(data)).rejects.toEqual(Error(message));
});

it('should throw error', async () => {
Expand Down
14 changes: 12 additions & 2 deletions src/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,20 @@ export const filterObjectPropsWithValue = (object = {}, value) => (
* @param {string} error - error message to put into the email body
* @returns {sting} mailto link with recipient, subject, and body
*/
export const getErrorReportMailto = (error = 'Unknown error occured') => {
export const getErrorReportMailto = ({
error = 'Unknown error occurred', errorMessage, networkIdentifier, serviceUrl, liskCoreVersion,
}) => {
const recipient = 'hubdev@lisk.io';
const subject = `User Reported Error - Lisk - ${VERSION}`; // eslint-disable-line no-undef
const body = encodeURIComponent(`\nImportant metadata for the team, please do not edit: \n\n${error}\n`);
const body = encodeURIComponent(`
\nImportant metadata for the team, please do not edit:
\r
Lisk Core Version: ${liskCoreVersion}, NetworkIdentifier: ${networkIdentifier}, ServiceURL: ${serviceUrl}
\r
Error Message: ${errorMessage}
\r
Transaction: ${error}
`);
return `mailto:${recipient}?&subject=${subject}&body=${body}`;
};

Expand Down

0 comments on commit 02904b7

Please sign in to comment.