Filter explorer error reports when using custom cluster (#11911)

This commit is contained in:
Justin Starry 2020-08-30 22:19:39 +08:00 committed by GitHub
parent 998f9725d0
commit 8932e4821d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 63 deletions

View File

@ -6,7 +6,7 @@ import {
TransactionSignature,
Connection,
} from "@solana/web3.js";
import { useCluster } from "../cluster";
import { useCluster, Cluster } from "../cluster";
import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache";
@ -78,6 +78,7 @@ export function HistoryProvider({ children }: HistoryProviderProps) {
async function fetchAccountHistory(
dispatch: Dispatch,
pubkey: PublicKey,
cluster: Cluster,
url: string,
options: { before?: TransactionSignature; limit: number }
) {
@ -102,7 +103,9 @@ async function fetchAccountHistory(
};
status = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
status = FetchStatus.FetchFailed;
}
dispatch({
@ -142,7 +145,7 @@ export function useAccountHistory(
}
export function useFetchAccountHistory() {
const { url } = useCluster();
const { cluster, url } = useCluster();
const state = React.useContext(StateContext);
const dispatch = React.useContext(DispatchContext);
if (!state || !dispatch) {
@ -151,15 +154,21 @@ export function useFetchAccountHistory() {
);
}
return (pubkey: PublicKey, refresh?: boolean) => {
const before = state.entries[pubkey.toBase58()];
if (!refresh && before?.data?.fetched && before.data.fetched.length > 0) {
if (before.data.foundOldest) return;
const oldest =
before.data.fetched[before.data.fetched.length - 1].signature;
fetchAccountHistory(dispatch, pubkey, url, { before: oldest, limit: 25 });
} else {
fetchAccountHistory(dispatch, pubkey, url, { limit: 25 });
}
};
return React.useCallback(
(pubkey: PublicKey, refresh?: boolean) => {
const before = state.entries[pubkey.toBase58()];
if (!refresh && before?.data?.fetched && before.data.fetched.length > 0) {
if (before.data.foundOldest) return;
const oldest =
before.data.fetched[before.data.fetched.length - 1].signature;
fetchAccountHistory(dispatch, pubkey, cluster, url, {
before: oldest,
limit: 25,
});
} else {
fetchAccountHistory(dispatch, pubkey, cluster, url, { limit: 25 });
}
},
[state, dispatch, cluster, url]
);
}

View File

@ -2,7 +2,7 @@ import React from "react";
import * as Sentry from "@sentry/react";
import { StakeAccount as StakeAccountWasm } from "solana-sdk-wasm";
import { PublicKey, Connection, StakeProgram } from "@solana/web3.js";
import { useCluster } from "../cluster";
import { useCluster, Cluster } from "../cluster";
import { HistoryProvider } from "./history";
import { TokensProvider, TOKEN_PROGRAM_ID } from "./tokens";
import { coerce } from "superstruct";
@ -72,6 +72,7 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
async function fetchAccountInfo(
dispatch: Dispatch,
pubkey: PublicKey,
cluster: Cluster,
url: string
) {
dispatch({
@ -149,7 +150,9 @@ async function fetchAccountInfo(
data = { pubkey, lamports, details };
fetchStatus = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
fetchStatus = FetchStatus.FetchFailed;
}
dispatch({
@ -231,11 +234,11 @@ export function useFetchAccountInfo() {
);
}
const { url } = useCluster();
const { cluster, url } = useCluster();
return React.useCallback(
(pubkey: PublicKey) => {
fetchAccountInfo(dispatch, pubkey, url);
fetchAccountInfo(dispatch, pubkey, cluster, url);
},
[dispatch, url]
[dispatch, cluster, url]
);
}

View File

@ -4,7 +4,7 @@ import { Connection, PublicKey } from "@solana/web3.js";
import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache";
import { TokenAccountInfo } from "validators/accounts/token";
import { useCluster } from "../cluster";
import { useCluster, Cluster } from "../cluster";
import { coerce } from "superstruct";
export type TokenInfoWithPubkey = {
@ -47,6 +47,7 @@ export const TOKEN_PROGRAM_ID = new PublicKey(
async function fetchAccountTokens(
dispatch: Dispatch,
pubkey: PublicKey,
cluster: Cluster,
url: string
) {
const key = pubkey.toBase58();
@ -73,7 +74,9 @@ async function fetchAccountTokens(
};
status = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
status = FetchStatus.FetchFailed;
}
dispatch({ type: ActionType.Update, url, status, data, key });
@ -101,8 +104,11 @@ export function useFetchAccountOwnedTokens() {
);
}
const { url } = useCluster();
return (pubkey: PublicKey) => {
fetchAccountTokens(dispatch, pubkey, url);
};
const { cluster, url } = useCluster();
return React.useCallback(
(pubkey: PublicKey) => {
fetchAccountTokens(dispatch, pubkey, cluster, url);
},
[dispatch, cluster, url]
);
}

View File

@ -183,9 +183,11 @@ async function updateCluster(
firstAvailableBlock,
});
} catch (error) {
Sentry.captureException(error, {
tags: { clusterUrl: clusterUrl(cluster, customUrl) },
});
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, {
tags: { clusterUrl: clusterUrl(cluster, customUrl) },
});
}
dispatch({ status: ClusterStatus.Failure, cluster, customUrl });
}
}

View File

@ -1,6 +1,6 @@
import React from "react";
import * as Sentry from "@sentry/react";
import { useCluster } from "providers/cluster";
import { useCluster, Cluster } from "providers/cluster";
import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache";
import {
@ -41,6 +41,7 @@ export function LargestAccountsProvider({ children }: ProviderProps) {
async function fetchLargestAccounts(
dispatch: Dispatch,
pubkey: PublicKey,
cluster: Cluster,
url: string
) {
dispatch({
@ -60,7 +61,9 @@ async function fetchLargestAccounts(
};
fetchStatus = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
fetchStatus = FetchStatus.FetchFailed;
}
dispatch({
@ -80,10 +83,13 @@ export function useFetchTokenLargestAccounts() {
);
}
const { url } = useCluster();
return (pubkey: PublicKey) => {
fetchLargestAccounts(dispatch, pubkey, url);
};
const { cluster, url } = useCluster();
return React.useCallback(
(pubkey: PublicKey) => {
fetchLargestAccounts(dispatch, pubkey, cluster, url);
},
[dispatch, cluster, url]
);
}
export function useTokenLargestTokens(

View File

@ -2,7 +2,7 @@ import React from "react";
import * as Sentry from "@sentry/react";
import { AccountBalancePair, Connection } from "@solana/web3.js";
import { useCluster, ClusterStatus } from "./cluster";
import { useCluster, ClusterStatus, Cluster } from "./cluster";
export enum Status {
Idle,
@ -25,7 +25,7 @@ const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
type Props = { children: React.ReactNode };
export function RichListProvider({ children }: Props) {
const [state, setState] = React.useState<State>(Status.Idle);
const { status: clusterStatus, url } = useCluster();
const { status: clusterStatus, cluster, url } = useCluster();
React.useEffect(() => {
if (state !== Status.Idle) {
@ -35,12 +35,12 @@ export function RichListProvider({ children }: Props) {
break;
}
case ClusterStatus.Connected: {
fetch(setState, url);
fetch(setState, cluster, url);
break;
}
}
}
}, [clusterStatus, url]); // eslint-disable-line react-hooks/exhaustive-deps
}, [clusterStatus, cluster, url]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<StateContext.Provider value={state}>
@ -51,7 +51,7 @@ export function RichListProvider({ children }: Props) {
);
}
async function fetch(dispatch: Dispatch, url: string) {
async function fetch(dispatch: Dispatch, cluster: Cluster, url: string) {
dispatch(Status.Connecting);
try {
@ -71,7 +71,9 @@ async function fetch(dispatch: Dispatch, url: string) {
return { total, circulating, nonCirculating };
});
} catch (err) {
Sentry.captureException(err, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(err, { tags: { url } });
}
dispatch("Failed to fetch top accounts");
}
}
@ -90,6 +92,8 @@ export function useFetchRichList() {
throw new Error(`useFetchRichList must be used within a RichListProvider`);
}
const { url } = useCluster();
return () => fetch(dispatch, url);
const { cluster, url } = useCluster();
return React.useCallback(() => {
fetch(dispatch, cluster, url);
}, [dispatch, cluster, url]);
}

View File

@ -2,7 +2,7 @@ import React from "react";
import * as Sentry from "@sentry/react";
import { Supply, Connection } from "@solana/web3.js";
import { useCluster, ClusterStatus } from "./cluster";
import { useCluster, ClusterStatus, Cluster } from "./cluster";
export enum Status {
Idle,
@ -19,15 +19,16 @@ const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
type Props = { children: React.ReactNode };
export function SupplyProvider({ children }: Props) {
const [state, setState] = React.useState<State>(Status.Idle);
const { status: clusterStatus, url } = useCluster();
const { status: clusterStatus, cluster, url } = useCluster();
React.useEffect(() => {
if (state !== Status.Idle) {
if (clusterStatus === ClusterStatus.Connecting)
setState(Status.Disconnected);
if (clusterStatus === ClusterStatus.Connected) fetch(setState, url);
if (clusterStatus === ClusterStatus.Connected)
fetch(setState, cluster, url);
}
}, [clusterStatus, url]); // eslint-disable-line react-hooks/exhaustive-deps
}, [clusterStatus, cluster, url]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<StateContext.Provider value={state}>
@ -38,7 +39,7 @@ export function SupplyProvider({ children }: Props) {
);
}
async function fetch(dispatch: Dispatch, url: string) {
async function fetch(dispatch: Dispatch, cluster: Cluster, url: string) {
dispatch(Status.Connecting);
try {
@ -51,7 +52,9 @@ async function fetch(dispatch: Dispatch, url: string) {
return supply;
});
} catch (err) {
Sentry.captureException(err, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(err, { tags: { url } });
}
dispatch("Failed to fetch supply");
}
}
@ -70,6 +73,8 @@ export function useFetchSupply() {
throw new Error(`useFetchSupply must be used within a SupplyProvider`);
}
const { url } = useCluster();
return () => fetch(dispatch, url);
const { cluster, url } = useCluster();
return React.useCallback(() => {
fetch(dispatch, cluster, url);
}, [dispatch, cluster, url]);
}

View File

@ -5,7 +5,7 @@ import {
TransactionSignature,
ParsedConfirmedTransaction,
} from "@solana/web3.js";
import { useCluster } from "../cluster";
import { useCluster, Cluster } from "../cluster";
import { CACHED_DETAILS, isCached } from "./cached";
import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache";
@ -43,6 +43,7 @@ export function DetailsProvider({ children }: DetailsProviderProps) {
async function fetchDetails(
dispatch: Dispatch,
signature: TransactionSignature,
cluster: Cluster,
url: string
) {
dispatch({
@ -64,7 +65,9 @@ async function fetchDetails(
);
fetchStatus = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
fetchStatus = FetchStatus.FetchFailed;
}
}
@ -85,10 +88,13 @@ export function useFetchTransactionDetails() {
);
}
const { url } = useCluster();
return (signature: TransactionSignature) => {
url && fetchDetails(dispatch, signature, url);
};
const { cluster, url } = useCluster();
return React.useCallback(
(signature: TransactionSignature) => {
url && fetchDetails(dispatch, signature, cluster, url);
},
[dispatch, cluster, url]
);
}
export function useTransactionDetails(

View File

@ -5,7 +5,7 @@ import {
Connection,
SignatureResult,
} from "@solana/web3.js";
import { useCluster } from "../cluster";
import { useCluster, Cluster } from "../cluster";
import { DetailsProvider } from "./details";
import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache";
@ -56,6 +56,7 @@ export function TransactionsProvider({ children }: TransactionsProviderProps) {
export async function fetchTransactionStatus(
dispatch: Dispatch,
signature: TransactionSignature,
cluster: Cluster,
url: string
) {
dispatch({
@ -84,7 +85,9 @@ export async function fetchTransactionStatus(
try {
blockTime = await connection.getBlockTime(value.slot);
} catch (error) {
Sentry.captureException(error, { tags: { slot: `${value.slot}` } });
Sentry.captureException(error, {
tags: { slot: `${value.slot}`, url },
});
}
let timestamp: Timestamp =
blockTime !== null ? blockTime : "unavailable";
@ -106,7 +109,9 @@ export async function fetchTransactionStatus(
data = { signature, info };
fetchStatus = FetchStatus.Fetched;
} catch (error) {
Sentry.captureException(error, { tags: { url } });
if (cluster !== Cluster.Custom) {
Sentry.captureException(error, { tags: { url } });
}
fetchStatus = FetchStatus.FetchFailed;
}
}
@ -156,8 +161,11 @@ export function useFetchTransactionStatus() {
);
}
const { url } = useCluster();
return (signature: TransactionSignature) => {
fetchTransactionStatus(dispatch, signature, url);
};
const { cluster, url } = useCluster();
return React.useCallback(
(signature: TransactionSignature) => {
fetchTransactionStatus(dispatch, signature, cluster, url);
},
[dispatch, cluster, url]
);
}