Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getHelpUrl config where users can go with error logs #2685

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 }}>
Need help?{' '}
<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
Loading