Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
20 changes: 20 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@
data-domain="app.jelly.xyz"
src="https://plausible.io/js/plausible.js"
></script>
<!-- datadog: start -->
<script
type="text/javascript"
src="https://www.datadoghq-browser-agent.com/datadog-logs-v4.js"
></script>
<script>
window.DD_LOGS &&
DD_LOGS.init({
clientToken: '%REACT_APP_DATADOG_CLIENT_TOKEN%',
site: 'datadoghq.eu',
forwardErrorsToLogs: false,
forwardConsoleLogs: [],
sampleRate: 100,
service: 'env:%REACT_APP_NODE_ENV%:jelly_web_client',
});
DD_LOGS.onReady(function () {
window.DD_LOGS_IS_READY = true;
});
</script>
<!-- datadog: end -->
</head>
<body>
<noscript
Expand Down
54 changes: 49 additions & 5 deletions src/store/features/marketplace/async-thunks/direct-buy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { Principal } from '@dfinity/principal';
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
import { notificationActions } from '../../notifications';
import { DirectBuy } from '../marketplace-slice';
import { DirectBuy, marketplaceActions } from '../marketplace-slice';
import config from '../../../../config/env';
import wicpIdlFactory from '../../../../declarations/wicp.did';
import marketplaceIdlFactory from '../../../../declarations/marketplace.did';
import { AppLog } from '../../../../utils/log';
import { KyasshuUrl } from '../../../../integrations/kyasshu';
import { errorMessageHandler } from '../../../../utils/error';
import { parseAmountToE8S } from '../../../../utils/formatters';
import { marketplaceActions } from '../marketplace-slice';
import type { RootState } from '../../../store';

import { log, getLogDescription } from '../../../../utils/datadog';

type DirectBuyProps = DefaultCallbacks & DirectBuy;

Expand All @@ -20,6 +22,16 @@ export const directBuy = createAsyncThunk<
>('marketplace/directBuy', async (params, { dispatch, getState }) => {
const { tokenId, price, onSuccess, onFailure } = params;

const {
plug: { principalId: plugPrincipal },
} = getState() as RootState;

const tokenIdTxt = tokenId.toString();
const logDescription = getLogDescription({
operation: 'directBuy',
parts: [tokenIdTxt, plugPrincipal || 'n/a'],
});

const {
marketplace: { sumOfUserAllowance },
}: any = getState();
Expand Down Expand Up @@ -61,11 +73,32 @@ export const directBuy = createAsyncThunk<
methodName: 'directBuy',
args: [nonFungibleContractAddress, tokenId],
onFail: (res: any) => {
log({
type: 'error',
description: logDescription,
data: {
tokenIdTxt,
plugPrincipal,
error: res.Err,
},
});

throw res;
},
onSuccess: async (res: any) => {
if ('Err' in res)
if ('Err' in res) {
log({
type: 'error',
description: logDescription,
data: {
tokenIdTxt,
plugPrincipal,
error: res.Err,
},
});

throw new Error(errorMessageHandler(res.Err));
}

if (typeof onSuccess !== 'function') return;

Expand All @@ -78,12 +111,23 @@ export const directBuy = createAsyncThunk<

const batchTxRes = await window.ic?.plug?.batchTransactions([
WICP_APPROVE,
// MKP_DEPOSIT_WICP,
MKP_DIRECT_BUY,
]);

if (!batchTxRes) {
throw new Error('Empty response');
const errorMsg = 'Empty response';

log({
type: 'error',
description: logDescription,
data: {
tokenIdTxt,
plugPrincipal,
error: errorMsg,
},
});

throw new Error(errorMsg);
}

return {
Expand Down
80 changes: 80 additions & 0 deletions src/utils/datadog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { OperationTypes } from '../constants/operations';

type LogType = 'debug' | 'info' | 'warn' | 'error';

interface LogBaseParams {
type: LogType;
description: string;
data?: Record<string, any>;
}

const RETRY_TIMEOUT = 1400;
const RETRY_MAX_ATTEMPTS = 1;

const logBase = (
{ type, description, data }: LogBaseParams,
retryCount = 1,
): void => {
if (!(window as any).DD_LOGS_IS_READY) {
if (retryCount > RETRY_MAX_ATTEMPTS) {
// eslint-disable-next-line no-console
console.warn('Oops! Logger not ready, retry attempted...');

return;
}

retryCount += 1;

setTimeout(() => {
// eslint-disable-next-line no-console
console.warn('Oops! Logger not ready, retrying...');

logBase(
{
type,
description,
data,
},
retryCount,
);
}, RETRY_TIMEOUT);
}

try {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
(window as any).DD_LOGS &&
(window as any).DD_LOGS.logger[type](description, data);
} catch (err) {
// eslint-disable-next-line no-console
console.error('Oops! Logger failed', err);
}
};

type LogParams = Pick<LogBaseParams, 'type' | 'description' | 'data'>;

export const log = ({ type, description, ...data }: LogParams) =>
logBase({
type,
description,
data,
});

type InfoParams = Pick<LogParams, 'description' | 'data'>;

export const logInfo = ({ description, ...args }: InfoParams) =>
logBase({
type: 'info',
description,
...args,
});

interface LogDescriptionParams {
operation: keyof typeof OperationTypes;
parts: string[];
}

export const getLogDescription = ({
operation,
parts,
}: LogDescriptionParams) => `${operation}:${parts.join(':')}`;