Skip to content

Commit

Permalink
feat: add error message to retry modal (#7643)
Browse files Browse the repository at this point in the history
## **Description**
 - Modify retry modal to display error message
 - Add transaction exception type for cancel and speedup transaction
- In Transaction component, when transactionObject has error, throw
exception base on the cancel / speedup
- In Transaction component, toggleRetry should take error message
instead of error
 - In Transaction component, error message should pass into retry modal

## **Related issues**

Fixes: #

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained what problem this PR is solving and how it
is solved.
- [x] I've linked related issues
- [x] I've included manual testing steps
- [x] I've included screenshots/recordings if applicable
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [x] I’ve properly set the pull request status:
  - [x] In case it's not yet "ready for review", I've set it to "draft".
- [x] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: Xiaoming Wang <dawnseeker8@gmail.com>
  • Loading branch information
stanleyyconsensys and dawnseeker8 authored Nov 10, 2023
1 parent d37ea80 commit 1072a0a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 18 deletions.
40 changes: 27 additions & 13 deletions app/components/UI/Transactions/RetryModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Text, {
TextVariant,
} from '../../../../component-library/components/Texts/Text';
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { fontStyles } from '../../../../styles/common';
import ActionModal from '../../ActionModal';
import { StyleSheet, View } from 'react-native';
import { strings } from '../../../../../locales/i18n';
import { useTheme } from '../../../../util/theme';
import ActionModal from '../../ActionModal';

const createStyles = (colors: any) =>
StyleSheet.create({
Expand All @@ -20,28 +22,34 @@ const createStyles = (colors: any) =>
width: '100%',
},
modalText: {
...(fontStyles.normal as any),
fontSize: 14,
textAlign: 'center',
paddingVertical: 8,
color: colors.text.default,
},
modalTitle: {
...(fontStyles.bold as any),
fontSize: 22,
textAlign: 'center',
color: colors.text.default,
},
modalErrText: {
textAlign: 'center',
paddingVertical: 8,
color: colors.error.default,
},
});

interface Props {
retryIsOpen: boolean;
onConfirmPress: () => void;
onCancelPress: () => void;
errorMsg: string;
errorMsg?: string;
}

const RetryModal = ({ retryIsOpen, onConfirmPress, onCancelPress }: Props) => {
const RetryModal = ({
retryIsOpen,
onConfirmPress,
onCancelPress,
errorMsg,
}: Props) => {
const { colors } = useTheme();
const styles = createStyles(colors);

Expand All @@ -56,12 +64,18 @@ const RetryModal = ({ retryIsOpen, onConfirmPress, onCancelPress }: Props) => {
onRequestClose={onCancelPress}
>
<View style={styles.modalView}>
<Text style={styles.modalTitle}>
<Text variant={TextVariant.HeadingLG} style={styles.modalTitle}>
{strings('transaction_update_retry_modal.title')}
</Text>
<Text style={styles.modalText}>
{strings('transaction_update_retry_modal.text')}
</Text>
{errorMsg ? (
<Text variant={TextVariant.BodyMD} style={styles.modalErrText}>
{errorMsg}
</Text>
) : (
<Text variant={TextVariant.BodyMD} style={styles.modalText}>
{strings('transaction_update_retry_modal.text')}
</Text>
)}
</View>
</ActionModal>
);
Expand Down
24 changes: 19 additions & 5 deletions app/components/UI/Transactions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ import {
import { selectContractExchangeRates } from '../../../selectors/tokenRatesController';
import { selectAccounts } from '../../../selectors/accountTrackerController';
import { selectSelectedAddress } from '../../../selectors/preferencesController';
import {
TransactionError,
CancelTransactionError,
SpeedupTransactionError,
} from '../../../core/Transaction/TransactionError';

const createStyles = (colors, typography) =>
StyleSheet.create({
Expand Down Expand Up @@ -469,28 +474,32 @@ class Transactions extends PureComponent {

handleSpeedUpTransactionFailure = (e) => {
const speedUpTxId = this.speedUpTxId;
const message = e instanceof TransactionError ? e.message : undefined;
Logger.error(e, { message: `speedUpTransaction failed `, speedUpTxId });
InteractionManager.runAfterInteractions(this.toggleRetry(e));
InteractionManager.runAfterInteractions(this.toggleRetry(message));
this.setState({
errorMsg: e.message,
speedUp1559IsOpen: false,
speedUpIsOpen: false,
});
};

handleCancelTransactionFailure = (e) => {
const cancelTxId = this.cancelTxId;
const message = e instanceof TransactionError ? e.message : undefined;
Logger.error(e, { message: `cancelTransaction failed `, cancelTxId });
InteractionManager.runAfterInteractions(this.toggleRetry(e));
InteractionManager.runAfterInteractions(this.toggleRetry(message));
this.setState({
errorMsg: e.message,
cancel1559IsOpen: false,
cancelIsOpen: false,
});
};

speedUpTransaction = async (transactionObject) => {
try {
if (transactionObject?.error) {
throw new SpeedupTransactionError(transactionObject.error);
}

await Engine.context.TransactionController.speedUpTransaction(
this.speedUpTxId,
transactionObject?.suggestedMaxFeePerGasHex && {
Expand Down Expand Up @@ -519,6 +528,10 @@ class Transactions extends PureComponent {

cancelTransaction = async (transactionObject) => {
try {
if (transactionObject?.error) {
throw new CancelTransactionError(transactionObject.error);
}

await Engine.context.TransactionController.stopTransaction(
this.cancelTxId,
transactionObject?.suggestedMaxFeePerGasHex && {
Expand Down Expand Up @@ -743,9 +756,10 @@ class Transactions extends PureComponent {
)}

<RetryModal
onCancelPress={this.toggleRetry}
onCancelPress={() => this.toggleRetry(undefined)}
onConfirmPress={this.retry}
retryIsOpen={this.state.retryIsOpen}
errorMsg={this.state.errorMsg}
/>
</View>
);
Expand Down
26 changes: 26 additions & 0 deletions app/core/Transaction/TransactionError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class TransactionError extends Error {
constructor(message: string) {
super(message);

Object.setPrototypeOf(this, TransactionError.prototype);

this.name = this.constructor.name;

if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
}

class ApproveTransactionError extends TransactionError {}

class CancelTransactionError extends TransactionError {}

class SpeedupTransactionError extends TransactionError {}

export {
TransactionError,
CancelTransactionError,
ApproveTransactionError,
SpeedupTransactionError,
};

0 comments on commit 1072a0a

Please sign in to comment.