diff --git a/src/components/shared/transactionResult/index.js b/src/components/shared/transactionResult/index.js index 196948d48e..2646378c8d 100644 --- a/src/components/shared/transactionResult/index.js +++ b/src/components/shared/transactionResult/index.js @@ -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 = { @@ -52,36 +54,48 @@ export const getBroadcastStatus = (transactions, isHardwareWalletError) => { export const TransactionResult = ({ title, message, t, status, children, illustration, className, -}) => ( -
- { - typeof illustration === 'string' - ? - : React.cloneElement(illustration) - } -

{title}

-

{message}

- {children} - { - errorTypes.includes(status.code) - ? ( - <> -

{t('Does the problem still persist?')}

- - - {t('Report the error via email')} - - - - ) - : null - } -
-); +}) => { + const network = useSelector(selectActiveTokenNetwork); + + return ( +
+ { + typeof illustration === 'string' + ? + : React.cloneElement(illustration) + } +

{title}

+

{message}

+ {children} + { + errorTypes.includes(status.code) + ? ( + <> +

{t('Does the problem still persist?')}

+ + + {t('Report the error via email')} + + + + ) + : null + } +
+ ); +}; export default TransactionResult; diff --git a/src/store/actions/transactions.js b/src/store/actions/transactions.js index c2a5d765db..bb319fcbcb 100644 --- a/src/store/actions/transactions.js +++ b/src/store/actions/transactions.js @@ -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 @@ -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 diff --git a/src/store/selectors.js b/src/store/selectors.js index dc06bc9fd2..d7bdc40939 100644 --- a/src/store/selectors.js +++ b/src/store/selectors.js @@ -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, @@ -30,4 +31,5 @@ export { selectAccountBalance, selectServiceUrl, selectCurrentBlockHeight, + selectActiveTokenNetwork, }; diff --git a/src/utils/api/http.js b/src/utils/api/http.js index c4223f4321..47fb8cf2ef 100644 --- a/src/utils/api/http.js +++ b/src/utils/api/http.js @@ -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(); diff --git a/src/utils/api/http.test.js b/src/utils/api/http.test.js index 4dbbbcc61a..7beeadc88f 100644 --- a/src/utils/api/http.test.js +++ b/src/utils/api/http.test.js @@ -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 () => { diff --git a/src/utils/helpers.js b/src/utils/helpers.js index 610e7e1071..fca77afc87 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -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}`; };