diff --git a/lib/api/useApiFetch.tsx b/lib/api/useApiFetch.tsx index a3de353c6f..cda519c1c1 100644 --- a/lib/api/useApiFetch.tsx +++ b/lib/api/useApiFetch.tsx @@ -21,6 +21,7 @@ export interface Params { pathParams?: ResourcePathParams; queryParams?: Record | number | boolean | undefined | null>; fetchParams?: Pick; + logError?: boolean; } export default function useApiFetch() { @@ -30,7 +31,7 @@ export default function useApiFetch() { return React.useCallback(( resourceName: R, - { pathParams, queryParams, fetchParams }: Params = {}, + { pathParams, queryParams, fetchParams, logError }: Params = {}, ) => { const apiToken = cookies.get(cookies.NAMES.API_TOKEN); @@ -58,7 +59,7 @@ export default function useApiFetch() { }, { resource: resource.path, - omitMonitoringLog: true, // disable logging of API errors to Rollbar + logError, }, ); }, [ fetch, csrfToken ]); diff --git a/lib/api/useApiQuery.tsx b/lib/api/useApiQuery.tsx index 8dfa918b8c..6cd58c024e 100644 --- a/lib/api/useApiQuery.tsx +++ b/lib/api/useApiQuery.tsx @@ -11,6 +11,7 @@ export interface Params | number | boolean | undefined>; fetchParams?: Pick; queryOptions?: Partial, ResourceError, D>, 'queryFn'>>; + logError?: boolean; } export function getResourceKey(resource: R, { pathParams, queryParams }: Params = {}) { @@ -23,7 +24,7 @@ export function getResourceKey(resource: R, { pathParams export default function useApiQuery>( resource: R, - { queryOptions, pathParams, queryParams, fetchParams }: Params = {}, + { queryOptions, pathParams, queryParams, fetchParams, logError }: Params = {}, ) { const apiFetch = useApiFetch(); @@ -33,7 +34,7 @@ export default function useApiQuery>" - return apiFetch(resource, { pathParams, queryParams, fetchParams: { ...fetchParams, signal } }) as Promise>; + return apiFetch(resource, { pathParams, queryParams, logError, fetchParams: { ...fetchParams, signal } }) as Promise>; }, ...queryOptions, }); diff --git a/lib/hooks/useAddressProfileApiQuery.tsx b/lib/hooks/useAddressProfileApiQuery.tsx index a637023f09..ef39555d43 100644 --- a/lib/hooks/useAddressProfileApiQuery.tsx +++ b/lib/hooks/useAddressProfileApiQuery.tsx @@ -27,7 +27,7 @@ export default function useAddressProfileApiQuery(hash: string | undefined, isEn return Promise.reject(); } - return fetch(feature.apiUrlTemplate.replace('{address}', hash), undefined, { omitMonitoringLog: true }); + return fetch(feature.apiUrlTemplate.replace('{address}', hash)); }, enabled: isEnabled && Boolean(hash), refetchOnMount: false, diff --git a/lib/hooks/useFetch.tsx b/lib/hooks/useFetch.tsx index caefe25ff4..4b50945f97 100644 --- a/lib/hooks/useFetch.tsx +++ b/lib/hooks/useFetch.tsx @@ -14,7 +14,7 @@ export interface Params { interface Meta { resource?: ResourcePath; - omitMonitoringLog?: boolean; + logError?: boolean; } export default function useFetch() { @@ -53,7 +53,7 @@ export default function useFetch() { statusText: response.statusText, }; - if (!meta?.omitMonitoringLog && rollbar) { + if (meta?.logError && rollbar) { rollbar.warn('Client fetch failed', { resource: meta?.resource, status_code: error.status, diff --git a/lib/hooks/useIsSafeAddress.tsx b/lib/hooks/useIsSafeAddress.tsx index 5796d175a9..7888050a6c 100644 --- a/lib/hooks/useIsSafeAddress.tsx +++ b/lib/hooks/useIsSafeAddress.tsx @@ -15,7 +15,7 @@ export default function useIsSafeAddress(hash: string | undefined): boolean { return Promise.reject(); } - return fetch(`${ feature.apiUrl }/${ hash }`, undefined, { omitMonitoringLog: true }); + return fetch(`${ feature.apiUrl }/${ hash }`); }, enabled: feature.isEnabled && Boolean(hash), refetchOnMount: false, diff --git a/ui/address/details/AddressQrCode.tsx b/ui/address/details/AddressQrCode.tsx index bbeaca7910..4a3f3970a0 100644 --- a/ui/address/details/AddressQrCode.tsx +++ b/ui/address/details/AddressQrCode.tsx @@ -52,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.'); - rollbar?.error('QR code generation failed'); + rollbar?.warn('QR code generation failed'); return; } diff --git a/ui/address/utils/useAddressQuery.ts b/ui/address/utils/useAddressQuery.ts index 3f1ae73929..ebeac2eb25 100644 --- a/ui/address/utils/useAddressQuery.ts +++ b/ui/address/utils/useAddressQuery.ts @@ -45,6 +45,7 @@ export default function useAddressQuery({ hash, isEnabled = true }: Params): Add return isRefetchEnabled ? 15 * SECOND : false; }, }, + logError: true, }); const rpcQuery = useQuery({ diff --git a/ui/shared/AppError/AppErrorBoundary.tsx b/ui/shared/AppError/AppErrorBoundary.tsx index 0560476c29..4c666967be 100644 --- a/ui/shared/AppError/AppErrorBoundary.tsx +++ b/ui/shared/AppError/AppErrorBoundary.tsx @@ -1,6 +1,7 @@ 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'; @@ -25,7 +26,16 @@ const AppErrorBoundary = ({ className, children, Container }: Props) => { }, [ className, Container ]); const handleError = React.useCallback((error: Error) => { - rollbar?.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 ( diff --git a/ui/snippets/auth/useRedirectForInvalidAuthToken.ts b/ui/snippets/auth/useRedirectForInvalidAuthToken.ts index fd75c7a06f..96634a138b 100644 --- a/ui/snippets/auth/useRedirectForInvalidAuthToken.ts +++ b/ui/snippets/auth/useRedirectForInvalidAuthToken.ts @@ -14,7 +14,6 @@ export default function useRedirectForInvalidAuthToken() { const apiToken = cookies.get(cookies.NAMES.API_TOKEN); if (apiToken) { - rollbar?.warn('Invalid API token'); cookies.remove(cookies.NAMES.API_TOKEN); window.location.assign('/'); }