mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Migrate from Sentry.io to Rollbar monitoring solution (#2403)
* basic Rollbar setup * remove sentry code * add rollback env to values for demo * [skip ci] adjust instance name * fix validator * don't log errors from API by default and change error levels * [skip ci] change default value for environment property * [skip ci] do not log api errors of address endpoint
This commit is contained in:
+1
-2
@@ -1,5 +1,4 @@
|
||||
NEXT_PUBLIC_SENTRY_DSN=https://sentry.io
|
||||
SENTRY_CSP_REPORT_URI=https://sentry.io
|
||||
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN=xxx
|
||||
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
|
||||
NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY=xxx
|
||||
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=UA-XXXXXX-X
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# TODO @tom2drum setup source maps for Rollbar
|
||||
name: Upload source maps to Sentry
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
@@ -43,9 +43,6 @@ yarn-error.log*
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Sentry
|
||||
.sentryclirc
|
||||
|
||||
**.decrypted~**
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
|
||||
@@ -25,10 +25,10 @@ export { default as nameService } from './nameService';
|
||||
export { default as publicTagsSubmission } from './publicTagsSubmission';
|
||||
export { default as restApiDocs } from './restApiDocs';
|
||||
export { default as rewards } from './rewards';
|
||||
export { default as rollbar } from './rollbar';
|
||||
export { default as rollup } from './rollup';
|
||||
export { default as safe } from './safe';
|
||||
export { default as saveOnGas } from './saveOnGas';
|
||||
export { default as sentry } from './sentry';
|
||||
export { default as sol2uml } from './sol2uml';
|
||||
export { default as stats } from './stats';
|
||||
export { default as suave } from './suave';
|
||||
|
||||
@@ -3,35 +3,34 @@ import type { Feature } from './types';
|
||||
import app from '../app';
|
||||
import { getEnvValue } from '../utils';
|
||||
|
||||
const dsn = getEnvValue('NEXT_PUBLIC_SENTRY_DSN');
|
||||
const clientToken = getEnvValue('NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN');
|
||||
const instance = (() => {
|
||||
const envValue = getEnvValue('NEXT_PUBLIC_APP_INSTANCE');
|
||||
if (envValue) {
|
||||
return envValue;
|
||||
}
|
||||
|
||||
return app.host?.replace('.blockscout.com', '').replaceAll('-', '_');
|
||||
return app.host?.replace('.blockscout.com', '').replace('.k8s-dev', '').replaceAll('-', '_');
|
||||
})();
|
||||
const environment = getEnvValue('NEXT_PUBLIC_APP_ENV') || 'production';
|
||||
const release = getEnvValue('NEXT_PUBLIC_GIT_TAG');
|
||||
const title = 'Sentry error monitoring';
|
||||
const codeVersion = getEnvValue('NEXT_PUBLIC_GIT_TAG') || getEnvValue('NEXT_PUBLIC_GIT_COMMIT_SHA');
|
||||
|
||||
const title = 'Rollbar error monitoring';
|
||||
|
||||
const config: Feature<{
|
||||
dsn: string;
|
||||
instance: string;
|
||||
release: string | undefined;
|
||||
clientToken: string;
|
||||
environment: string;
|
||||
enableTracing: boolean;
|
||||
instance: string | undefined;
|
||||
codeVersion: string | undefined;
|
||||
}> = (() => {
|
||||
if (dsn && instance && environment) {
|
||||
if (clientToken) {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
dsn,
|
||||
instance,
|
||||
release,
|
||||
clientToken,
|
||||
environment,
|
||||
enableTracing: getEnvValue('NEXT_PUBLIC_SENTRY_ENABLE_TRACING') === 'true',
|
||||
instance,
|
||||
codeVersion,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://eth.drpc.org?ref=559183','text':'Public
|
||||
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://merits.blockscout.com
|
||||
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-mainnet.safe.global
|
||||
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true
|
||||
NEXT_PUBLIC_SENTRY_ENABLE_TRACING=true
|
||||
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED=true
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://stats-eth-main.k8s-prod-1.blockscout.com
|
||||
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
|
||||
|
||||
@@ -64,7 +64,6 @@ NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-c
|
||||
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://sepolia.drpc.org?ref=559183','text':'Public RPC'}]
|
||||
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://merits.blockscout.com
|
||||
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-sepolia.safe.global
|
||||
NEXT_PUBLIC_SENTRY_ENABLE_TRACING=true
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://stats-sepolia.k8s.blockscout.com
|
||||
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=noves
|
||||
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
|
||||
|
||||
@@ -7,6 +7,7 @@ NEXT_PUBLIC_APP_PROTOCOL=http
|
||||
NEXT_PUBLIC_APP_HOST=localhost
|
||||
NEXT_PUBLIC_APP_PORT=3000
|
||||
NEXT_PUBLIC_APP_ENV=development
|
||||
NEXT_PUBLIC_APP_INSTANCE=rubber_duck
|
||||
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
|
||||
|
||||
# Instance ENVs
|
||||
@@ -60,7 +61,6 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
|
||||
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/sepolia-testnet.png
|
||||
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://sepolia.drpc.org?ref=559183','text':'Public RPC'}]
|
||||
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-sepolia.safe.global
|
||||
NEXT_PUBLIC_SENTRY_ENABLE_TRACING=true
|
||||
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED=true
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://stats-sepolia.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
|
||||
|
||||
@@ -147,6 +147,16 @@ function printDeprecationWarning(envsMap: Record<string, string>) {
|
||||
console.log('❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗\n');
|
||||
}
|
||||
|
||||
if (
|
||||
(envsMap.NEXT_PUBLIC_SENTRY_DSN || envsMap.SENTRY_CSP_REPORT_URI || envsMap.NEXT_PUBLIC_SENTRY_ENABLE_TRACING) &&
|
||||
envsMap.NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN
|
||||
) {
|
||||
console.log('❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗');
|
||||
// eslint-disable-next-line max-len
|
||||
console.warn('The Sentry monitoring is now deprecated and will be removed in the next release. Please migrate to the Rollbar error monitoring.');
|
||||
console.log('❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗\n');
|
||||
}
|
||||
|
||||
if (
|
||||
envsMap.NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR ||
|
||||
envsMap.NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND
|
||||
@@ -178,5 +188,14 @@ function checkDeprecatedEnvs(envsMap: Record<string, string>) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (
|
||||
(envsMap.NEXT_PUBLIC_SENTRY_DSN || envsMap.SENTRY_CSP_REPORT_URI || envsMap.NEXT_PUBLIC_SENTRY_ENABLE_TRACING) &&
|
||||
!envsMap.NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN
|
||||
) {
|
||||
// eslint-disable-next-line max-len
|
||||
console.log('🚨 The Sentry error monitoring is no longer supported. Please migrate to the Rollbar error monitoring.');
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
!silent && console.log('👍 All good!\n');
|
||||
}
|
||||
|
||||
@@ -372,6 +372,7 @@ const adsBannerSchema = yup
|
||||
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE: adButlerConfigSchema,
|
||||
});
|
||||
|
||||
// DEPRECATED
|
||||
const sentrySchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
@@ -389,20 +390,6 @@ const sentrySchema = yup
|
||||
is: (value: string) => Boolean(value),
|
||||
then: (schema) => schema,
|
||||
}),
|
||||
NEXT_PUBLIC_APP_INSTANCE: yup
|
||||
.string()
|
||||
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
||||
is: (value: string) => Boolean(value),
|
||||
then: (schema) => schema,
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_APP_INSTANCE cannot not be used without NEXT_PUBLIC_SENTRY_DSN'),
|
||||
}),
|
||||
NEXT_PUBLIC_APP_ENV: yup
|
||||
.string()
|
||||
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
||||
is: (value: string) => Boolean(value),
|
||||
then: (schema) => schema,
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_APP_ENV cannot not be used without NEXT_PUBLIC_SENTRY_DSN'),
|
||||
}),
|
||||
});
|
||||
|
||||
const accountSchema = yup
|
||||
@@ -592,6 +579,8 @@ const schema = yup
|
||||
NEXT_PUBLIC_APP_HOST: yup.string().required(),
|
||||
NEXT_PUBLIC_APP_PROTOCOL: yup.string().oneOf(protocols),
|
||||
NEXT_PUBLIC_APP_PORT: yup.number().positive().integer(),
|
||||
NEXT_PUBLIC_APP_ENV: yup.string(),
|
||||
NEXT_PUBLIC_APP_INSTANCE: yup.string(),
|
||||
|
||||
// 2. Blockchain parameters
|
||||
NEXT_PUBLIC_NETWORK_NAME: yup.string().required(),
|
||||
@@ -898,6 +887,7 @@ const schema = yup
|
||||
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: yup.string(),
|
||||
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: yup.string(),
|
||||
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY: yup.string(),
|
||||
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN: yup.string(),
|
||||
|
||||
// Misc
|
||||
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NEXT_PUBLIC_SENTRY_DSN=https://sentry.io
|
||||
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN=https://rollbar.com
|
||||
NEXT_PUBLIC_AUTH_URL=https://example.com
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_LOGOUT_URL=https://example.com
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
NEXT_PUBLIC_SENTRY_DSN=https://sentry.io
|
||||
SENTRY_CSP_REPORT_URI=https://sentry.io
|
||||
NEXT_PUBLIC_SENTRY_ENABLE_TRACING=true
|
||||
NEXT_PUBLIC_APP_ENV=production
|
||||
NEXT_PUBLIC_APP_INSTANCE=duck
|
||||
@@ -47,8 +47,7 @@ frontend:
|
||||
memory: 384Mi
|
||||
cpu: 250m
|
||||
env:
|
||||
NEXT_PUBLIC_APP_ENV: development
|
||||
NEXT_PUBLIC_APP_INSTANCE: review_L2
|
||||
NEXT_PUBLIC_APP_ENV: review
|
||||
NEXT_PUBLIC_NETWORK_LOGO: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/base.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/base.svg
|
||||
NEXT_PUBLIC_FEATURED_NETWORKS: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/base-mainnet.json
|
||||
@@ -73,8 +72,6 @@ frontend:
|
||||
NEXT_PUBLIC_NAVIGATION_LAYOUT: horizontal
|
||||
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES: "['/blocks','/name-domains']"
|
||||
envFromSecret:
|
||||
NEXT_PUBLIC_SENTRY_DSN: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_SENTRY_DSN
|
||||
SENTRY_CSP_REPORT_URI: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/SENTRY_CSP_REPORT_URI
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
|
||||
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
|
||||
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
|
||||
|
||||
@@ -47,8 +47,7 @@ frontend:
|
||||
memory: 384Mi
|
||||
cpu: 250m
|
||||
env:
|
||||
NEXT_PUBLIC_APP_ENV: development
|
||||
NEXT_PUBLIC_APP_INSTANCE: review
|
||||
NEXT_PUBLIC_APP_ENV: review
|
||||
NEXT_PUBLIC_FEATURED_NETWORKS: https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/featured-networks/eth-sepolia.json
|
||||
NEXT_PUBLIC_NETWORK_LOGO: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/sepolia.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/sepolia.png
|
||||
@@ -79,11 +78,10 @@ frontend:
|
||||
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES: "['/apps']"
|
||||
PROMETHEUS_METRICS_ENABLED: true
|
||||
envFromSecret:
|
||||
NEXT_PUBLIC_SENTRY_DSN: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_SENTRY_DSN
|
||||
SENTRY_CSP_REPORT_URI: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/SENTRY_CSP_REPORT_URI
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
|
||||
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
|
||||
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
|
||||
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY
|
||||
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN
|
||||
NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY
|
||||
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN
|
||||
|
||||
+13
-2
@@ -60,6 +60,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
|
||||
- [MetaSuites extension](ENVS.md#metasuites-extension)
|
||||
- [Validators list](ENVS.md#validators-list)
|
||||
- [Sentry error monitoring](ENVS.md#sentry-error-monitoring)
|
||||
- [Rollbar error monitoring](ENVS.md#rollbar-error-monitoring)
|
||||
- [OpenTelemetry](ENVS.md#opentelemetry)
|
||||
- [DeFi dropdown](ENVS.md#defi-dropdown)
|
||||
- [Multichain balance button](ENVS.md#multichain-balance-button)
|
||||
@@ -77,6 +78,8 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
|
||||
| NEXT_PUBLIC_APP_PROTOCOL | `http \| https` | App url schema | - | `https` | `http` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_APP_HOST | `string` | App host | Required | - | `blockscout.com` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_APP_PORT | `number` | Port where app is running | - | `3000` | `3001` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_APP_ENV | `string` | App env (e.g development, staging, production, etc.). | - | `production` | `staging` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_APP_INSTANCE | `string` | Name of app instance. Used for app monitoring purposes. If not provided, it will be constructed from `NEXT_PUBLIC_APP_HOST` | - | - | `wonderful_kepler` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_USE_NEXT_JS_PROXY | `boolean` | Tells the app to proxy all APIs request through the NextJS app. **We strongly advise not to use it in the production environment**, since it can lead to performance issues of the NodeJS server | - | `false` | `true` | v1.8.0+ |
|
||||
|
||||
|
||||
@@ -738,13 +741,21 @@ The feature enables the Validators page which provides detailed information abou
|
||||
|
||||
### Sentry error monitoring
|
||||
|
||||
_Note_ This feature is **deprecated**. All ENV variables will be removed in the future releases.
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_SENTRY_DSN | `string` | Client key for your Sentry.io app | Required | - | `<your-secret>` | v1.0.x+ |
|
||||
| SENTRY_CSP_REPORT_URI | `string` | URL for sending CSP-reports to your Sentry.io app | - | - | `<your-secret>` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_SENTRY_ENABLE_TRACING | `boolean` | Enables tracing and performance monitoring in Sentry.io | - | `false` | `true` | v1.17.0+ |
|
||||
| NEXT_PUBLIC_APP_ENV | `string` | App env (e.g development, review or production). Passed as `environment` property to Sentry config | - | `production` | `production` | v1.0.x+ |
|
||||
| NEXT_PUBLIC_APP_INSTANCE | `string` | Name of app instance. Used as custom tag `app_instance` value in the main Sentry scope. If not provided, it will be constructed from `NEXT_PUBLIC_APP_HOST` | - | - | `wonderful_kepler` | v1.0.x+ |
|
||||
|
||||
|
||||
|
||||
### Rollbar error monitoring
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN | `string` | Client token for your Rollbar project | Required | - | `<your-secret>` | v1.37.x+ |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface Params<R extends ResourceName> {
|
||||
pathParams?: ResourcePathParams<R>;
|
||||
queryParams?: Record<string, string | Array<string> | number | boolean | undefined | null>;
|
||||
fetchParams?: Pick<FetchParams, 'body' | 'method' | 'signal' | 'headers'>;
|
||||
logError?: boolean;
|
||||
}
|
||||
|
||||
export default function useApiFetch() {
|
||||
@@ -30,7 +31,7 @@ export default function useApiFetch() {
|
||||
|
||||
return React.useCallback(<R extends ResourceName, SuccessType = unknown, ErrorType = unknown>(
|
||||
resourceName: R,
|
||||
{ pathParams, queryParams, fetchParams }: Params<R> = {},
|
||||
{ pathParams, queryParams, fetchParams, logError }: Params<R> = {},
|
||||
) => {
|
||||
const apiToken = cookies.get(cookies.NAMES.API_TOKEN);
|
||||
|
||||
@@ -58,7 +59,7 @@ export default function useApiFetch() {
|
||||
},
|
||||
{
|
||||
resource: resource.path,
|
||||
omitSentryErrorLog: true, // disable logging of API errors to Sentry
|
||||
logError,
|
||||
},
|
||||
);
|
||||
}, [ fetch, csrfToken ]);
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface Params<R extends ResourceName, E = unknown, D = ResourcePayload
|
||||
queryParams?: Record<string, string | Array<string> | number | boolean | undefined>;
|
||||
fetchParams?: Pick<FetchParams, 'body' | 'method' | 'headers'>;
|
||||
queryOptions?: Partial<Omit<UseQueryOptions<ResourcePayload<R>, ResourceError<E>, D>, 'queryFn'>>;
|
||||
logError?: boolean;
|
||||
}
|
||||
|
||||
export function getResourceKey<R extends ResourceName>(resource: R, { pathParams, queryParams }: Params<R> = {}) {
|
||||
@@ -23,7 +24,7 @@ export function getResourceKey<R extends ResourceName>(resource: R, { pathParams
|
||||
|
||||
export default function useApiQuery<R extends ResourceName, E = unknown, D = ResourcePayload<R>>(
|
||||
resource: R,
|
||||
{ queryOptions, pathParams, queryParams, fetchParams }: Params<R, E, D> = {},
|
||||
{ queryOptions, pathParams, queryParams, fetchParams, logError }: Params<R, E, D> = {},
|
||||
) {
|
||||
const apiFetch = useApiFetch();
|
||||
|
||||
@@ -33,7 +34,7 @@ export default function useApiQuery<R extends ResourceName, E = unknown, D = Res
|
||||
// all errors and error typing is handled by react-query
|
||||
// so error response will never go to the data
|
||||
// that's why we are safe here to do type conversion "as Promise<ResourcePayload<R>>"
|
||||
return apiFetch(resource, { pathParams, queryParams, fetchParams: { ...fetchParams, signal } }) as Promise<ResourcePayload<R>>;
|
||||
return apiFetch(resource, { pathParams, queryParams, logError, fetchParams: { ...fetchParams, signal } }) as Promise<ResourcePayload<R>>;
|
||||
},
|
||||
...queryOptions,
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function useAddressProfileApiQuery(hash: string | undefined, isEn
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return fetch(feature.apiUrlTemplate.replace('{address}', hash), undefined, { omitSentryErrorLog: true });
|
||||
return fetch(feature.apiUrlTemplate.replace('{address}', hash));
|
||||
},
|
||||
enabled: isEnabled && Boolean(hash),
|
||||
refetchOnMount: false,
|
||||
|
||||
+11
-10
@@ -1,8 +1,8 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import React from 'react';
|
||||
|
||||
import isBodyAllowed from 'lib/api/isBodyAllowed';
|
||||
import type { ResourceError, ResourcePath } from 'lib/api/resources';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
|
||||
export interface Params {
|
||||
method?: RequestInit['method'];
|
||||
@@ -14,10 +14,12 @@ export interface Params {
|
||||
|
||||
interface Meta {
|
||||
resource?: ResourcePath;
|
||||
omitSentryErrorLog?: boolean;
|
||||
logError?: boolean;
|
||||
}
|
||||
|
||||
export default function useFetch() {
|
||||
const rollbar = useRollbar();
|
||||
|
||||
return React.useCallback(<Success, Error>(path: string, params?: Params, meta?: Meta): Promise<Success | ResourceError<Error>> => {
|
||||
const _body = params?.body;
|
||||
const isFormData = _body instanceof FormData;
|
||||
@@ -51,13 +53,12 @@ export default function useFetch() {
|
||||
statusText: response.statusText,
|
||||
};
|
||||
|
||||
if (!meta?.omitSentryErrorLog) {
|
||||
Sentry.captureException(new Error('Client fetch failed'), { tags: {
|
||||
source: 'fetch',
|
||||
'source.resource': meta?.resource,
|
||||
'status.code': error.status,
|
||||
'status.text': error.statusText,
|
||||
} });
|
||||
if (meta?.logError && rollbar) {
|
||||
rollbar.warn('Client fetch failed', {
|
||||
resource: meta?.resource,
|
||||
status_code: error.status,
|
||||
status_text: error.statusText,
|
||||
});
|
||||
}
|
||||
|
||||
return response.json().then(
|
||||
@@ -75,5 +76,5 @@ export default function useFetch() {
|
||||
return response.json() as Promise<Success>;
|
||||
}
|
||||
});
|
||||
}, [ ]);
|
||||
}, [ rollbar ]);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import buildUrl from 'lib/api/buildUrl';
|
||||
@@ -6,9 +5,11 @@ import isNeedProxy from 'lib/api/isNeedProxy';
|
||||
import { getResourceKey } from 'lib/api/useApiQuery';
|
||||
import * as cookies from 'lib/cookies';
|
||||
import useFetch from 'lib/hooks/useFetch';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
|
||||
export default function useGetCsrfToken() {
|
||||
const nodeApiFetch = useFetch();
|
||||
const rollbar = useRollbar();
|
||||
|
||||
return useQuery({
|
||||
queryKey: getResourceKey('csrf'),
|
||||
@@ -19,12 +20,11 @@ export default function useGetCsrfToken() {
|
||||
const csrfFromHeader = apiResponse.headers.get('x-bs-account-csrf');
|
||||
|
||||
if (!csrfFromHeader) {
|
||||
Sentry.captureException(new Error('Client fetch failed'), { tags: {
|
||||
source: 'fetch',
|
||||
'source.resource': 'csrf',
|
||||
'status.code': 500,
|
||||
'status.text': 'Unable to obtain csrf token from header',
|
||||
} });
|
||||
rollbar?.warn('Client fetch failed', {
|
||||
resource: 'csrf',
|
||||
status_code: 500,
|
||||
status_text: 'Unable to obtain csrf token from header',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function useIsSafeAddress(hash: string | undefined): boolean {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return fetch(`${ feature.apiUrl }/${ hash }`, undefined, { omitSentryErrorLog: true });
|
||||
return fetch(`${ feature.apiUrl }/${ hash }`);
|
||||
},
|
||||
enabled: feature.isEnabled && Boolean(hash),
|
||||
refetchOnMount: false,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Provider as DefaultProvider, useRollbar as useRollbarDefault } from '@rollbar/react';
|
||||
import type React from 'react';
|
||||
import type { Configuration } from 'rollbar';
|
||||
|
||||
import config from 'configs/app';
|
||||
|
||||
const feature = config.features.rollbar;
|
||||
|
||||
const FallbackProvider = ({ children }: { children: React.ReactNode }) => children;
|
||||
|
||||
const useRollbarFallback = (): undefined => {};
|
||||
|
||||
export const Provider = feature.isEnabled ? DefaultProvider : FallbackProvider;
|
||||
export const useRollbar = feature.isEnabled ? useRollbarDefault : useRollbarFallback;
|
||||
|
||||
export const clientConfig: Configuration | undefined = feature.isEnabled ? {
|
||||
accessToken: feature.clientToken,
|
||||
environment: feature.environment,
|
||||
payload: {
|
||||
code_version: feature.codeVersion,
|
||||
app_instance: feature.instance,
|
||||
},
|
||||
} : undefined;
|
||||
@@ -1,108 +0,0 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { BrowserTracing } from '@sentry/tracing';
|
||||
|
||||
import appConfig from 'configs/app';
|
||||
import { RESOURCE_LOAD_ERROR_MESSAGE } from 'lib/errors/throwOnResourceLoadError';
|
||||
|
||||
const feature = appConfig.features.sentry;
|
||||
|
||||
export const config: Sentry.BrowserOptions | undefined = (() => {
|
||||
if (!feature.isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tracesSampleRate: number | undefined = (() => {
|
||||
switch (feature.environment) {
|
||||
case 'development':
|
||||
return 1;
|
||||
case 'staging':
|
||||
return 0.75;
|
||||
case 'production':
|
||||
return 0.2;
|
||||
}
|
||||
})();
|
||||
|
||||
return {
|
||||
environment: feature.environment,
|
||||
dsn: feature.dsn,
|
||||
release: feature.release,
|
||||
enableTracing: feature.enableTracing,
|
||||
tracesSampleRate,
|
||||
integrations: feature.enableTracing ? [ new BrowserTracing() ] : undefined,
|
||||
|
||||
// error filtering settings
|
||||
// were taken from here - https://docs.sentry.io/platforms/node/guides/azure-functions/configuration/filtering/#decluttering-sentry
|
||||
ignoreErrors: [
|
||||
// Random plugins/extensions
|
||||
'top.GLOBALS',
|
||||
// See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html
|
||||
'originalCreateNotification',
|
||||
'canvas.contentDocument',
|
||||
'MyApp_RemoveAllHighlights',
|
||||
'http://tt.epicplay.com',
|
||||
'Can\'t find variable: ZiteReader',
|
||||
'jigsaw is not defined',
|
||||
'ComboSearch is not defined',
|
||||
'http://loading.retry.widdit.com/',
|
||||
'atomicFindClose',
|
||||
// Facebook borked
|
||||
'fb_xd_fragment',
|
||||
// ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha)
|
||||
// See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy
|
||||
'bmi_SafeAddOnload',
|
||||
'EBCallBackMessageReceived',
|
||||
// See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
|
||||
'conduitPage',
|
||||
// Generic error code from errors outside the security sandbox
|
||||
'Script error.',
|
||||
|
||||
// Relay and WalletConnect errors
|
||||
'The quota has been exceeded',
|
||||
'Attempt to connect to relay via',
|
||||
'WebSocket connection failed for URL: wss://relay.walletconnect.com',
|
||||
|
||||
// API errors
|
||||
RESOURCE_LOAD_ERROR_MESSAGE,
|
||||
],
|
||||
denyUrls: [
|
||||
// Facebook flakiness
|
||||
/graph\.facebook\.com/i,
|
||||
// Facebook blocked
|
||||
/connect\.facebook\.net\/en_US\/all\.js/i,
|
||||
// Woopra flakiness
|
||||
/eatdifferent\.com\.woopra-ns\.com/i,
|
||||
/static\.woopra\.com\/js\/woopra\.js/i,
|
||||
// Chrome and other extensions
|
||||
/extensions\//i,
|
||||
/^chrome:\/\//i,
|
||||
/^chrome-extension:\/\//i,
|
||||
/^moz-extension:\/\//i,
|
||||
// Other plugins
|
||||
/127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
|
||||
/webappstoolbarba\.texthelp\.com\//i,
|
||||
/metrics\.itunes\.apple\.com\.edgesuite\.net\//i,
|
||||
|
||||
// AD fetch failed errors
|
||||
/czilladx\.com/i,
|
||||
/coinzilla\.com/i,
|
||||
/coinzilla\.io/i,
|
||||
/slise\.xyz/i,
|
||||
],
|
||||
};
|
||||
})();
|
||||
|
||||
export function configureScope(scope: Sentry.Scope) {
|
||||
if (!feature.isEnabled) {
|
||||
return;
|
||||
}
|
||||
scope.setTag('app_instance', feature.instance);
|
||||
}
|
||||
|
||||
export function init() {
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentry.init(config);
|
||||
Sentry.configureScope(configureScope);
|
||||
}
|
||||
+1
-7
@@ -18,13 +18,7 @@ const moduleExports = {
|
||||
'swagger-ui-react',
|
||||
],
|
||||
reactStrictMode: true,
|
||||
webpack(config, { webpack }) {
|
||||
config.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
__SENTRY_DEBUG__: false,
|
||||
__SENTRY_TRACING__: false,
|
||||
}),
|
||||
);
|
||||
webpack(config) {
|
||||
config.module.rules.push(
|
||||
{
|
||||
test: /\.svg$/,
|
||||
|
||||
@@ -9,7 +9,6 @@ import useAdblockDetect from 'lib/hooks/useAdblockDetect';
|
||||
import useGetCsrfToken from 'lib/hooks/useGetCsrfToken';
|
||||
import * as metadata from 'lib/metadata';
|
||||
import * as mixpanel from 'lib/mixpanel';
|
||||
import { init as initSentry } from 'lib/sentry/config';
|
||||
|
||||
interface Props<Pathname extends Route['pathname']> {
|
||||
pathname: Pathname;
|
||||
@@ -18,8 +17,6 @@ interface Props<Pathname extends Route['pathname']> {
|
||||
apiData?: PageProps<Pathname>['apiData'];
|
||||
}
|
||||
|
||||
initSentry();
|
||||
|
||||
const PageNextJs = <Pathname extends Route['pathname']>(props: Props<Pathname>) => {
|
||||
const { title, description, opengraph, canonical } = metadata.generate(props, props.apiData);
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ function generateCspPolicy() {
|
||||
descriptors.marketplace(),
|
||||
descriptors.mixpanel(),
|
||||
descriptors.monaco(),
|
||||
descriptors.rollbar(),
|
||||
descriptors.safe(),
|
||||
descriptors.sentry(),
|
||||
descriptors.usernameApi(),
|
||||
descriptors.walletConnect(),
|
||||
);
|
||||
|
||||
@@ -11,25 +11,6 @@ const MAIN_DOMAINS = [
|
||||
config.app.host,
|
||||
].filter(Boolean);
|
||||
|
||||
const getCspReportUrl = () => {
|
||||
try {
|
||||
const sentryFeature = config.features.sentry;
|
||||
if (!sentryFeature.isEnabled || !process.env.SENTRY_CSP_REPORT_URI) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = new URL(process.env.SENTRY_CSP_REPORT_URI);
|
||||
|
||||
// https://docs.sentry.io/product/security-policy-reporting/#additional-configuration
|
||||
url.searchParams.set('sentry_environment', sentryFeature.environment);
|
||||
sentryFeature.release && url.searchParams.set('sentry_release', sentryFeature.release);
|
||||
|
||||
return url.toString();
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const externalFontsDomains = (() => {
|
||||
try {
|
||||
return [
|
||||
@@ -152,17 +133,5 @@ export function app(): CspDev.DirectiveDescriptor {
|
||||
// allow remix.ethereum.org to embed our contract page in iframe
|
||||
'remix.ethereum.org',
|
||||
],
|
||||
|
||||
...((() => {
|
||||
if (!config.features.sentry.isEnabled) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
'report-uri': [
|
||||
getCspReportUrl(),
|
||||
].filter(Boolean),
|
||||
};
|
||||
})()),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export { helia } from './helia';
|
||||
export { marketplace } from './marketplace';
|
||||
export { mixpanel } from './mixpanel';
|
||||
export { monaco } from './monaco';
|
||||
export { rollbar } from './rollbar';
|
||||
export { safe } from './safe';
|
||||
export { sentry } from './sentry';
|
||||
export { usernameApi } from './usernameApi';
|
||||
export { walletConnect } from './walletConnect';
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type CspDev from 'csp-dev';
|
||||
|
||||
import config from 'configs/app';
|
||||
|
||||
export function rollbar(): CspDev.DirectiveDescriptor {
|
||||
if (!config.features.rollbar.isEnabled) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
'connect-src': [
|
||||
'api.rollbar.com',
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import type CspDev from 'csp-dev';
|
||||
|
||||
export function sentry(): CspDev.DirectiveDescriptor {
|
||||
return {
|
||||
'connect-src': [
|
||||
'sentry.io',
|
||||
'*.sentry.io',
|
||||
],
|
||||
};
|
||||
}
|
||||
+2
-3
@@ -59,10 +59,8 @@
|
||||
"@opentelemetry/sdk-node": "0.49.1",
|
||||
"@opentelemetry/sdk-trace-node": "1.22.0",
|
||||
"@opentelemetry/semantic-conventions": "1.22.0",
|
||||
"@rollbar/react": "0.12.0-beta",
|
||||
"@scure/base": "1.1.9",
|
||||
"@sentry/cli": "^2.21.2",
|
||||
"@sentry/react": "7.24.0",
|
||||
"@sentry/tracing": "7.24.0",
|
||||
"@slise/embed-react": "^2.2.0",
|
||||
"@tanstack/react-query": "5.55.4",
|
||||
"@tanstack/react-query-devtools": "5.55.4",
|
||||
@@ -110,6 +108,7 @@
|
||||
"react-jazzicon": "^1.0.4",
|
||||
"react-number-format": "^5.3.1",
|
||||
"react-scroll": "^1.8.7",
|
||||
"rollbar": "2.26.4",
|
||||
"swagger-ui-react": "^5.9.0",
|
||||
"use-font-face-observer": "^1.2.1",
|
||||
"valibot": "0.38.0",
|
||||
|
||||
+5
-3
@@ -1,19 +1,21 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { NextPageWithLayout } from 'nextjs/types';
|
||||
|
||||
import PageNextJs from 'nextjs/PageNextJs';
|
||||
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
import AppError from 'ui/shared/AppError/AppError';
|
||||
import LayoutError from 'ui/shared/layout/LayoutError';
|
||||
|
||||
const error = new Error('Not found', { cause: { status: 404 } });
|
||||
|
||||
const Page: NextPageWithLayout = () => {
|
||||
const rollbar = useRollbar();
|
||||
|
||||
React.useEffect(() => {
|
||||
Sentry.captureException(new Error('Page not found'), { tags: { source: '404' } });
|
||||
}, []);
|
||||
rollbar?.error('Page not found');
|
||||
}, [ rollbar ]);
|
||||
|
||||
return (
|
||||
<PageNextJs pathname="/404">
|
||||
|
||||
+30
-33
@@ -1,6 +1,5 @@
|
||||
import { type ChakraProps } from '@chakra-ui/react';
|
||||
import { GrowthBookProvider } from '@growthbook/growthbook-react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import type { AppProps } from 'next/app';
|
||||
@@ -19,6 +18,7 @@ import { SettingsContextProvider } from 'lib/contexts/settings';
|
||||
import { growthBook } from 'lib/growthbook/init';
|
||||
import useLoadFeatures from 'lib/growthbook/useLoadFeatures';
|
||||
import useNotifyOnNavigation from 'lib/hooks/useNotifyOnNavigation';
|
||||
import { clientConfig as rollbarConfig, Provider as RollbarProvider } from 'lib/rollbar';
|
||||
import { SocketProvider } from 'lib/socket/context';
|
||||
import RewardsLoginModal from 'ui/rewards/login/RewardsLoginModal';
|
||||
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
|
||||
@@ -53,42 +53,39 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||
|
||||
const queryClient = useQueryClientConfig();
|
||||
|
||||
const handleError = React.useCallback((error: Error) => {
|
||||
Sentry.captureException(error);
|
||||
}, []);
|
||||
|
||||
const getLayout = Component.getLayout ?? ((page) => <Layout>{ page }</Layout>);
|
||||
|
||||
return (
|
||||
<ChakraProvider cookies={ pageProps.cookies }>
|
||||
<AppErrorBoundary
|
||||
{ ...ERROR_SCREEN_STYLES }
|
||||
onError={ handleError }
|
||||
Container={ AppErrorGlobalContainer }
|
||||
>
|
||||
<Web3ModalProvider>
|
||||
<AppContextProvider pageProps={ pageProps }>
|
||||
<QueryClientProvider client={ queryClient }>
|
||||
<GrowthBookProvider growthbook={ growthBook }>
|
||||
<ScrollDirectionProvider>
|
||||
<SocketProvider url={ `${ config.api.socket }${ config.api.basePath }/socket/v2` }>
|
||||
<RewardsContextProvider>
|
||||
<MarketplaceContextProvider>
|
||||
<SettingsContextProvider>
|
||||
{ getLayout(<Component { ...pageProps }/>) }
|
||||
{ config.features.rewards.isEnabled && <RewardsLoginModal/> }
|
||||
</SettingsContextProvider>
|
||||
</MarketplaceContextProvider>
|
||||
</RewardsContextProvider>
|
||||
</SocketProvider>
|
||||
</ScrollDirectionProvider>
|
||||
</GrowthBookProvider>
|
||||
<ReactQueryDevtools buttonPosition="bottom-left" position="left"/>
|
||||
<GoogleAnalytics/>
|
||||
</QueryClientProvider>
|
||||
</AppContextProvider>
|
||||
</Web3ModalProvider>
|
||||
</AppErrorBoundary>
|
||||
<RollbarProvider config={ rollbarConfig }>
|
||||
<AppErrorBoundary
|
||||
{ ...ERROR_SCREEN_STYLES }
|
||||
Container={ AppErrorGlobalContainer }
|
||||
>
|
||||
<Web3ModalProvider>
|
||||
<AppContextProvider pageProps={ pageProps }>
|
||||
<QueryClientProvider client={ queryClient }>
|
||||
<GrowthBookProvider growthbook={ growthBook }>
|
||||
<ScrollDirectionProvider>
|
||||
<SocketProvider url={ `${ config.api.socket }${ config.api.basePath }/socket/v2` }>
|
||||
<RewardsContextProvider>
|
||||
<MarketplaceContextProvider>
|
||||
<SettingsContextProvider>
|
||||
{ getLayout(<Component { ...pageProps }/>) }
|
||||
{ config.features.rewards.isEnabled && <RewardsLoginModal/> }
|
||||
</SettingsContextProvider>
|
||||
</MarketplaceContextProvider>
|
||||
</RewardsContextProvider>
|
||||
</SocketProvider>
|
||||
</ScrollDirectionProvider>
|
||||
</GrowthBookProvider>
|
||||
<ReactQueryDevtools buttonPosition="bottom-left" position="left"/>
|
||||
<GoogleAnalytics/>
|
||||
</QueryClientProvider>
|
||||
</AppContextProvider>
|
||||
</Web3ModalProvider>
|
||||
</AppErrorBoundary>
|
||||
</RollbarProvider>
|
||||
</ChakraProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
IconButton,
|
||||
Skeleton,
|
||||
} from '@chakra-ui/react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import QRCode from 'qrcode';
|
||||
import React from 'react';
|
||||
@@ -23,6 +22,7 @@ import type { Address as AddressType } from 'types/api/address';
|
||||
|
||||
import getPageType from 'lib/mixpanel/getPageType';
|
||||
import * as mixpanel from 'lib/mixpanel/index';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
||||
import IconSvg from 'ui/shared/IconSvg';
|
||||
|
||||
@@ -40,6 +40,7 @@ const AddressQrCode = ({ address, className, isLoading }: Props) => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
|
||||
const router = useRouter();
|
||||
const rollbar = useRollbar();
|
||||
|
||||
const [ qr, setQr ] = React.useState('');
|
||||
const [ error, setError ] = React.useState('');
|
||||
@@ -51,7 +52,7 @@ const AddressQrCode = ({ address, className, isLoading }: Props) => {
|
||||
QRCode.toString(address.hash, SVG_OPTIONS, (error: Error | null | undefined, svg: string) => {
|
||||
if (error) {
|
||||
setError('We were unable to generate QR code.');
|
||||
Sentry.captureException(error, { tags: { source: 'qr_code' } });
|
||||
rollbar?.warn('QR code generation failed');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,7 +61,7 @@ const AddressQrCode = ({ address, className, isLoading }: Props) => {
|
||||
mixpanel.logEvent(mixpanel.EventTypes.QR_CODE, { 'Page type': pageType });
|
||||
});
|
||||
}
|
||||
}, [ address.hash, isOpen, onClose, pageType ]);
|
||||
}, [ address.hash, isOpen, onClose, pageType, rollbar ]);
|
||||
|
||||
if (isLoading) {
|
||||
return <Skeleton className={ className } w="36px" h="32px" borderRadius="base"/>;
|
||||
|
||||
+7
-7
@@ -1,5 +1,4 @@
|
||||
import { VStack, Textarea, Button, Alert, AlertTitle, AlertDescription, Code, Flex, Box } from '@chakra-ui/react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import mixpanel from 'mixpanel-browser';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
@@ -9,12 +8,13 @@ import * as cookies from 'lib/cookies';
|
||||
import useFeatureValue from 'lib/growthbook/useFeatureValue';
|
||||
import useGradualIncrement from 'lib/hooks/useGradualIncrement';
|
||||
import useToast from 'lib/hooks/useToast';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
|
||||
const Login = () => {
|
||||
const rollbar = useRollbar();
|
||||
const toast = useToast();
|
||||
const [ num, setNum ] = useGradualIncrement(0);
|
||||
|
||||
const testFeature = useFeatureValue('test_value', 'fallback');
|
||||
|
||||
const [ isFormVisible, setFormVisibility ] = React.useState(false);
|
||||
@@ -23,12 +23,12 @@ const Login = () => {
|
||||
React.useEffect(() => {
|
||||
const token = cookies.get(cookies.NAMES.API_TOKEN);
|
||||
setFormVisibility(Boolean(!token && config.features.account.isEnabled));
|
||||
// throw new Error('Test error');
|
||||
// throw new Error('Render error');
|
||||
}, []);
|
||||
|
||||
const checkSentry = React.useCallback(() => {
|
||||
Sentry.captureException(new Error('Test error'), { tags: { source: 'test' } });
|
||||
}, []);
|
||||
const checkRollbar = React.useCallback(() => {
|
||||
rollbar?.error('Test error', { payload: 'foo' });
|
||||
}, [ rollbar ]);
|
||||
|
||||
const checkMixpanel = React.useCallback(() => {
|
||||
mixpanel.track('Test event', { my_prop: 'foo bar' });
|
||||
@@ -80,7 +80,7 @@ const Login = () => {
|
||||
</>
|
||||
) }
|
||||
<Flex columnGap={ 2 }>
|
||||
<Button colorScheme="red" onClick={ checkSentry }>Check Sentry</Button>
|
||||
<Button colorScheme="red" onClick={ checkRollbar }>Check Rollbar</Button>
|
||||
<Button colorScheme="teal" onClick={ checkMixpanel }>Check Mixpanel</Button>
|
||||
</Flex>
|
||||
<Flex columnGap={ 2 } alignItems="center">
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { chakra } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import getErrorCauseStatusCode from 'lib/errors/getErrorCauseStatusCode';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
import ErrorBoundary from 'ui/shared/ErrorBoundary';
|
||||
|
||||
import AppError from './AppError';
|
||||
@@ -8,11 +10,12 @@ import AppError from './AppError';
|
||||
interface Props {
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
onError?: (error: Error) => void;
|
||||
Container?: React.FC<{ children: React.ReactNode }>;
|
||||
}
|
||||
|
||||
const AppErrorBoundary = ({ className, children, onError, Container }: Props) => {
|
||||
const AppErrorBoundary = ({ className, children, Container }: Props) => {
|
||||
|
||||
const rollbar = useRollbar();
|
||||
|
||||
const renderErrorScreen = React.useCallback((error?: Error) => {
|
||||
const content = <AppError error={ error } className={ className }/>;
|
||||
@@ -22,8 +25,21 @@ const AppErrorBoundary = ({ className, children, onError, Container }: Props) =>
|
||||
return content;
|
||||
}, [ className, Container ]);
|
||||
|
||||
const handleError = React.useCallback((error: Error) => {
|
||||
const statusCode = getErrorCauseStatusCode(error);
|
||||
if (statusCode || !rollbar) {
|
||||
// For now, we are not interested in logging errors from the API.
|
||||
// If an error from a resource should be logged, please consider passing "logError: true" to the useApiQuery or useApiFetch hook.
|
||||
return;
|
||||
}
|
||||
|
||||
// To this point, there can only be errors that lead to a page crash.
|
||||
// Therefore, we set the error level to "critical."
|
||||
rollbar.critical(error);
|
||||
}, [ rollbar ]);
|
||||
|
||||
return (
|
||||
<ErrorBoundary renderErrorScreen={ renderErrorScreen } onError={ onError }>
|
||||
<ErrorBoundary renderErrorScreen={ renderErrorScreen } onError={ handleError }>
|
||||
{ children }
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import React from 'react';
|
||||
|
||||
import * as cookies from 'lib/cookies';
|
||||
import { useRollbar } from 'lib/rollbar';
|
||||
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
|
||||
|
||||
export default function useRedirectForInvalidAuthToken() {
|
||||
const rollbar = useRollbar();
|
||||
const profileQuery = useProfileQuery();
|
||||
const errorStatus = profileQuery.error?.status;
|
||||
|
||||
@@ -13,10 +14,9 @@ export default function useRedirectForInvalidAuthToken() {
|
||||
const apiToken = cookies.get(cookies.NAMES.API_TOKEN);
|
||||
|
||||
if (apiToken) {
|
||||
Sentry.captureException(new Error('Invalid API token'), { tags: { source: 'invalid_api_token' } });
|
||||
cookies.remove(cookies.NAMES.API_TOKEN);
|
||||
window.location.assign('/');
|
||||
}
|
||||
}
|
||||
}, [ errorStatus ]);
|
||||
}, [ errorStatus, rollbar ]);
|
||||
}
|
||||
|
||||
@@ -5415,6 +5415,13 @@
|
||||
prop-types "^15.7.2"
|
||||
tslib "^2.3.0"
|
||||
|
||||
"@rollbar/[email protected]":
|
||||
version "0.12.0-beta"
|
||||
resolved "https://registry.yarnpkg.com/@rollbar/react/-/react-0.12.0-beta.tgz#b80dfab1535ece358a0e98a4f26aadee8b54edda"
|
||||
integrity sha512-8udBX0lJwdBBq+O/jqDXpg/giHt8bo/Us1IlTkHEdCBO18Cjj7sxWJ80OPFxiPRNwZgZnhf2HbxQxvLN+4FeJA==
|
||||
dependencies:
|
||||
tiny-invariant "^1.1.0"
|
||||
|
||||
"@rollup/pluginutils@^5.0.0":
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33"
|
||||
@@ -5600,70 +5607,6 @@
|
||||
"@noble/hashes" "~1.5.0"
|
||||
"@scure/base" "~1.1.8"
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.24.0.tgz#3e657f8032322d07f98486f44e048fcdbc3aaff7"
|
||||
integrity sha512-G2eeYWF7rIz1Dm8PCQiuuTzctrrJSWqD5MCWOICqHr8FrxOPVsVO3Qa/B7/+BSpHd+V7sSUU17oFu41SAWZCOg==
|
||||
dependencies:
|
||||
"@sentry/core" "7.24.0"
|
||||
"@sentry/types" "7.24.0"
|
||||
"@sentry/utils" "7.24.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/cli@^2.21.2":
|
||||
version "2.21.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.21.2.tgz#89e5633ff48a83d078c76c6997fffd4b68b2da1c"
|
||||
integrity sha512-X1nye89zl+QV3FSuQDGItfM51tW9PQ7ce0TtV/12DgGgTVEgnVp5uvO3wX5XauHvulQzRPzwUL3ZK+yS5bAwCw==
|
||||
dependencies:
|
||||
https-proxy-agent "^5.0.0"
|
||||
node-fetch "^2.6.7"
|
||||
progress "^2.0.3"
|
||||
proxy-from-env "^1.1.0"
|
||||
which "^2.0.2"
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.24.0.tgz#e856a071c702279854d6e5221957d61cd48036cc"
|
||||
integrity sha512-QVRtmnaWEI0/MHIfBozgsMfh+7WU6OfpvUd72x1Dpk3Zk6Zs7Hqq0YfxfeBd7ApjNjGogPl1beaHcHAHlr3IyA==
|
||||
dependencies:
|
||||
"@sentry/types" "7.24.0"
|
||||
"@sentry/utils" "7.24.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.24.0.tgz#aa51b09bad8c5d7af163a28a4718abb1e68ea232"
|
||||
integrity sha512-uW6j7wrPxg7UillUVdsjrsIPqqPEAN/PdotR2O75Qh7s0aR7+Le8i29C4VeW/iubXhlxF/qFvnXwqG5Ji4GwBg==
|
||||
dependencies:
|
||||
"@sentry/browser" "7.24.0"
|
||||
"@sentry/types" "7.24.0"
|
||||
"@sentry/utils" "7.24.0"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.24.0.tgz#d9477a2da9c902ca9663cd4cd87ba279f73f212c"
|
||||
integrity sha512-O/4hE/lYM6+hM4K5O06pWNuHzZb2ex5f2497bxkwxq17wpJhVp1oDuz8hbWNL7BUNeIbeDpqunBHQzzmVRbL1Q==
|
||||
dependencies:
|
||||
"@sentry/core" "7.24.0"
|
||||
"@sentry/types" "7.24.0"
|
||||
"@sentry/utils" "7.24.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.24.0.tgz#1acc841efe7bd56fc3eb647a613dba92631e8413"
|
||||
integrity sha512-Xs4r9esBPieJUA6cGmMqfSQiinILdlhScjM+NqDSzxOo8+LRCJzckTLhUttBGVlaAoa4hjCEsfkHA1tVV1DycA==
|
||||
|
||||
"@sentry/[email protected]":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.24.0.tgz#73f100dc8942e73353473eaf3168e5052e2f45be"
|
||||
integrity sha512-baaRDhHWHTyhmR6V8YKSo0NvN+D17pIKRDmb2vpWHVpTjobKCivNBLRoy3VhnIMS/24XyZnL028QLwkUNLg1Ug==
|
||||
dependencies:
|
||||
"@sentry/types" "7.24.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sideway/address@^4.1.3":
|
||||
version "4.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
||||
@@ -8270,6 +8213,11 @@ async-mutex@^0.2.6:
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
async@~3.2.3:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
|
||||
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
@@ -9015,6 +8963,11 @@ consola@^3.2.3:
|
||||
resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f"
|
||||
integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==
|
||||
|
||||
[email protected]:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.3.0.tgz#84900902a18c47a5eba932be75fa44d23e8af861"
|
||||
integrity sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==
|
||||
|
||||
convert-hrtime@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-5.0.0.tgz#f2131236d4598b95de856926a67100a0a97e9fa3"
|
||||
@@ -9610,6 +9563,13 @@ debug@^3.2.7:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decache@^3.0.5:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/decache/-/decache-3.1.0.tgz#4f5036fbd6581fcc97237ac3954a244b9536c2da"
|
||||
integrity sha512-p7D6wJ5EJFFq1CcF2lu1XeqKFLBob8jRQGNAvFLTsV3CbSKBl3VtliAVlUIGz2i9H6kEFnI2Amaft5ZopIG2Fw==
|
||||
dependencies:
|
||||
find "^0.2.4"
|
||||
|
||||
decamelize@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
@@ -10052,6 +10012,13 @@ error-ex@^1.3.1:
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
error-stack-parser@^2.0.4:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286"
|
||||
integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==
|
||||
dependencies:
|
||||
stackframe "^1.3.4"
|
||||
|
||||
[email protected]:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
|
||||
@@ -10959,6 +10926,13 @@ find-yarn-workspace-root@^2.0.0:
|
||||
dependencies:
|
||||
micromatch "^4.0.2"
|
||||
|
||||
find@^0.2.4:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c"
|
||||
integrity sha512-7a4/LCiInB9xYMnAUEjLilL9FKclwbwK7VlXw+h5jMvT2TDFeYFCHM24O1XdnC/on/hx8mxVO3FTQkyHZnOghQ==
|
||||
dependencies:
|
||||
traverse-chain "~0.1.0"
|
||||
|
||||
flat-cache@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
|
||||
@@ -11658,7 +11632,7 @@ http-shutdown@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f"
|
||||
integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==
|
||||
|
||||
https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
|
||||
https-proxy-agent@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
|
||||
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
|
||||
@@ -13158,6 +13132,11 @@ json-stable-stringify@^1.0.2:
|
||||
dependencies:
|
||||
jsonify "^0.0.1"
|
||||
|
||||
json-stringify-safe@~5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
|
||||
|
||||
json5@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
@@ -13536,6 +13515,11 @@ lru-cache@^6.0.0:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lru-cache@~2.2.1:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
|
||||
integrity sha512-Q5pAgXs+WEAfoEdw2qKQhNFFhMoFMTYqRVKKUMnzuiR7oKFHS7fWo848cPcTKw+4j/IdN17NyzdhVKgabFV0EA==
|
||||
|
||||
lz-string@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
|
||||
@@ -14920,11 +14904,6 @@ progress-events@^1.0.0, progress-events@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/progress-events/-/progress-events-1.0.1.tgz#693b6d4153f08c1418ae3cd5fcad8596c91db7e8"
|
||||
integrity sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==
|
||||
|
||||
progress@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
[email protected]:
|
||||
version "15.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.1.1.tgz#71ba84371241acd173181b04a436782c246f3652"
|
||||
@@ -15658,6 +15637,11 @@ repeat-string@^1.5.2:
|
||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
|
||||
|
||||
request-ip@~3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-3.3.0.tgz#863451e8fec03847d44f223e30a5d63e369fa611"
|
||||
integrity sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
@@ -15780,6 +15764,21 @@ robust-predicates@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a"
|
||||
integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==
|
||||
|
||||
[email protected]:
|
||||
version "2.26.4"
|
||||
resolved "https://registry.yarnpkg.com/rollbar/-/rollbar-2.26.4.tgz#05e47d3b1f52ab6da9f88710ec66371a76cdc3c9"
|
||||
integrity sha512-JKmrj6riYm9ZPJisgxljgH4uCsvjMHDHXrinDF7aAFaP+eoF51HomVPtLcDTYLsrJ568aKVNLUhedFajONBwSg==
|
||||
dependencies:
|
||||
async "~3.2.3"
|
||||
console-polyfill "0.3.0"
|
||||
error-stack-parser "^2.0.4"
|
||||
json-stringify-safe "~5.0.0"
|
||||
lru-cache "~2.2.1"
|
||||
request-ip "~3.3.0"
|
||||
source-map "^0.5.7"
|
||||
optionalDependencies:
|
||||
decache "^3.0.5"
|
||||
|
||||
rollup-plugin-visualizer@^5.9.2:
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz#661542191ce78ee4f378995297260d0c1efb1302"
|
||||
@@ -16249,6 +16248,11 @@ stack-utils@^2.0.3:
|
||||
dependencies:
|
||||
escape-string-regexp "^2.0.0"
|
||||
|
||||
stackframe@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310"
|
||||
integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
|
||||
|
||||
stampit@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/stampit/-/stampit-4.3.2.tgz#cfd3f607dd628a161ce6305621597994b4d56573"
|
||||
@@ -16823,6 +16827,11 @@ tiny-invariant@^1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
|
||||
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
|
||||
|
||||
tiny-invariant@^1.1.0:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
|
||||
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
|
||||
|
||||
tiny-parse-argv@^2.2.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-parse-argv/-/tiny-parse-argv-2.4.0.tgz#8612163a88104a5af9a64e4775cd1e091d4fa265"
|
||||
@@ -16889,6 +16898,11 @@ tr46@~0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
traverse-chain@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
|
||||
integrity sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==
|
||||
|
||||
traverse@~0.6.6:
|
||||
version "0.6.7"
|
||||
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.7.tgz#46961cd2d57dd8706c36664acde06a248f1173fe"
|
||||
@@ -16974,7 +16988,7 @@ tsconfig-paths@^3.15.0:
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
[email protected], tslib@^1.8.1, tslib@^1.9.3:
|
||||
[email protected], tslib@^1.8.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
@@ -17682,7 +17696,7 @@ which-typed-array@^1.1.2, which-typed-array@^1.1.8, which-typed-array@^1.1.9:
|
||||
has-tostringtag "^1.0.0"
|
||||
is-typed-array "^1.1.10"
|
||||
|
||||
which@^2.0.1, which@^2.0.2:
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
|
||||
Reference in New Issue
Block a user