Skip to content

Commit

Permalink
Add getHelpUrl config where users can go with error logs (#2685)
Browse files Browse the repository at this point in the history
* optional supportUrl & error log copy button

* dont freak out when user rejects in their wallet

* remove g flag because it behaves funny

* get help bro

* the

* more generic property name

* dont say help twice
  • Loading branch information
artursapek authored Sep 20, 2024
1 parent 6dbc1f1 commit 418068b
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 25 deletions.
3 changes: 3 additions & 0 deletions wormhole-connect/src/config/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export type UiConfig = {
walletConnectProjectId?: string;
showHamburgerMenu: boolean;
previewMode?: boolean; // Disables making transfers

getHelpUrl?: string;
};

export interface DefaultInputs {
Expand Down Expand Up @@ -85,6 +87,7 @@ export function createUiConfig(customConfig: Partial<UiConfig>): UiConfig {
pageHeader: customConfig?.pageHeader,
pageSubHeader: customConfig?.pageSubHeader,
menu: customConfig?.menu ?? [],
getHelpUrl: customConfig?.getHelpUrl,
searchTx: customConfig?.searchTx,
moreTokens: customConfig?.moreTokens,
moreChains: customConfig?.moreChains,
Expand Down
9 changes: 5 additions & 4 deletions wormhole-connect/src/utils/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { Chain } from '@wormhole-foundation/sdk';

// TODO SDKV2
// attempt to capture errors using regex
export const INSUFFICIENT_ALLOWANCE_REGEX =
/[I|i]nsufficient token allowance/gm;
export const USER_REJECTED_REGEX =
/rejected the request|[R|r]ejected from user|user cancel|aborted by user/gm;
export const INSUFFICIENT_ALLOWANCE_REGEX = /insufficient token allowance/im;
export const USER_REJECTED_REGEX = new RegExp(
'user rejected|rejected the request|rejected from user|user cancel|aborted by user',
'mi',
);

export function interpretTransferError(
e: any,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useState } from 'react';
import { makeStyles } from 'tss-react/mui';
import config from 'config';
import AlertBannerV2 from 'components/v2/AlertBanner';
import { copyTextToClipboard } from 'utils';
import { Box, Typography } from '@mui/material';
import CopyIcon from '@mui/icons-material/ContentCopy';
import DoneIcon from '@mui/icons-material/Done';

type Props = {
humanError?: string;
internalError?: any;
};

const useStyles = makeStyles()((theme: any) => ({
copyIcon: {
fontSize: '14px',
},
doneIcon: {
fontSize: '14px',
color: theme.palette.success.main,
},
}));

export default ({ humanError, internalError }: Props) => {
const { classes } = useStyles();

const [justCopied, setJustCopied] = useState(false);

if (humanError === undefined) {
return null;
}

const getHelp =
internalError && internalError.message && config.ui.getHelpUrl ? (
<Typography fontSize={14} sx={{ marginTop: 1 }}>
Having trouble?{' '}
<a
href="#"
onClick={() => {
copyTextToClipboard(internalError.message);
setJustCopied(true);
setTimeout(() => setJustCopied(false), 3000);
}}
>
Copy the error logs{' '}
{justCopied ? (
<DoneIcon className={classes.doneIcon} />
) : (
<CopyIcon className={classes.copyIcon} />
)}
</a>
{' and '}
<a href={config.ui.getHelpUrl} target="_blank">
ask for help
</a>
.
</Typography>
) : null;

return (
<Box sx={{ marginBottom: 2 }}>
<AlertBannerV2
error
content={humanError}
show={true}
testId="send-error-message"
/>
{getHelp}
</Box>
);
};
48 changes: 27 additions & 21 deletions wormhole-connect/src/views/v2/Bridge/ReviewTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import IconButton from '@mui/material/IconButton';
import { getTokenDetails } from 'telemetry';
import { Context } from 'sdklegacy';

import AlertBannerV2 from 'components/v2/AlertBanner';
import Button from 'components/v2/Button';
import config from 'config';
import { RoutesConfig } from 'config/routes';
Expand Down Expand Up @@ -42,6 +41,8 @@ import { RelayerFee } from 'store/relay';
import { amount as sdkAmount } from '@wormhole-foundation/sdk';
import { toDecimals } from 'utils/balance';
import { useUSDamountGetter } from 'hooks/useUSDamountGetter';
import SendError from './SendError';
import { ERR_USER_REJECTED } from 'telemetry/types';

const useStyles = makeStyles()((theme) => ({
container: {
Expand Down Expand Up @@ -71,7 +72,10 @@ const ReviewTransaction = (props: Props) => {

const mobile = useMediaQuery(theme.breakpoints.down('sm'));

const [sendError, setSendError] = useState('');
const [sendError, setSendError] = useState<string | undefined>(undefined);
const [sendErrorInternal, setSendErrorInternal] = useState<any | undefined>(
undefined,
);

const routeContext = useContext(RouteContext);

Expand Down Expand Up @@ -112,7 +116,7 @@ const ReviewTransaction = (props: Props) => {
: undefined;

const send = async () => {
setSendError('');
setSendError(undefined);

// Pre-check of required values
if (
Expand Down Expand Up @@ -160,6 +164,7 @@ const ReviewTransaction = (props: Props) => {
}
} catch (e) {
setSendError('Error validating transfer');
setSendErrorInternal(e);
console.error(e);
return;
}
Expand Down Expand Up @@ -276,21 +281,27 @@ const ReviewTransaction = (props: Props) => {
dispatch(setSendTx(txId));
dispatch(setRedeemRoute(route));
dispatch(setAppRoute('redeem'));
setSendError('');
setSendError(undefined);
} catch (e: any) {
console.error('Wormhole Connect: error completing transfer', e);

const [uiError, transferError] = interpretTransferError(e, sourceChain);

// Show error in UI
setSendError(uiError);

// Trigger transfer error event to integrator
config.triggerEvent({
type: 'transfer.error',
error: transferError,
details: transferDetails,
});
if (transferError.type === ERR_USER_REJECTED) {
// User intentionally rejected in their wallet. This is not an error in the sense
// that something went wrong.
} else {
console.error('Wormhole Connect: error completing transfer', e);

// Show error in UI
setSendError(uiError);
setSendErrorInternal(e);

// Trigger transfer error event to integrator
config.triggerEvent({
type: 'transfer.error',
error: transferError,
details: transferDetails,
});
}
} finally {
dispatch(setIsTransactionInProgress(false));
}
Expand Down Expand Up @@ -383,12 +394,7 @@ const ReviewTransaction = (props: Props) => {
disabled={isGasSliderDisabled}
/>
</Collapse>
<AlertBannerV2
error
content={sendError}
show={!!sendError}
testId="send-error-message"
/>
<SendError humanError={sendError} internalError={sendErrorInternal} />
{confirmTransactionButton}
</Stack>
);
Expand Down

0 comments on commit 418068b

Please sign in to comment.