Commit 62675e88 authored by tom's avatar tom

setup filters for Rollbar events

parent 878e8950
export const ABSENT_PARAM_ERROR_MESSAGE = 'Required param not provided';
export default function throwOnAbsentParamError(param: unknown) {
if (!param) {
throw new Error('Required param not provided', { cause: { status: 404 } });
throw new Error(ABSENT_PARAM_ERROR_MESSAGE, { cause: { status: 404 } });
}
}
......@@ -5,11 +5,9 @@ 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'),
......@@ -20,11 +18,13 @@ export default function useGetCsrfToken() {
const csrfFromHeader = apiResponse.headers.get('x-bs-account-csrf');
if (!csrfFromHeader) {
rollbar?.warn('Client fetch failed', {
resource: 'csrf',
status_code: 500,
status_text: 'Unable to obtain csrf token from header',
});
// I am not sure should we log this error or not
// so I commented it out for now
// rollbar?.warn('Client fetch failed', {
// resource: 'csrf',
// status_code: 500,
// status_text: 'Unable to obtain csrf token from header',
// });
return;
}
......
......@@ -3,6 +3,10 @@ import type React from 'react';
import type { Configuration } from 'rollbar';
import config from 'configs/app';
import { ABSENT_PARAM_ERROR_MESSAGE } from 'lib/errors/throwOnAbsentParamError';
import { RESOURCE_LOAD_ERROR_MESSAGE } from 'lib/errors/throwOnResourceLoadError';
import { isBot, isHeadlessBrowser, isNextJsChunkError, getRequestInfo } from './utils';
const feature = config.features.rollbar;
......@@ -20,4 +24,42 @@ export const clientConfig: Configuration | undefined = feature.isEnabled ? {
code_version: feature.codeVersion,
app_instance: feature.instance,
},
checkIgnore(isUncaught, args, item) {
if (isBot(window.navigator.userAgent)) {
return true;
}
if (isHeadlessBrowser(window.navigator.userAgent)) {
return true;
}
if (isNextJsChunkError(getRequestInfo(item)?.url)) {
return true;
}
return false;
},
hostSafeList: [ config.app.host ].filter(Boolean),
ignoredMessages: [
// these are React errors - "NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node."
// they could be caused by browser extensions
// one of the examples - https://github.com/facebook/react/issues/11538
// we can ignore them for now
'NotFoundError',
// these are errors that we throw on when make a call to the API
RESOURCE_LOAD_ERROR_MESSAGE,
ABSENT_PARAM_ERROR_MESSAGE,
// Filter out network-related errors that are usually not actionable
'Network Error',
'Failed to fetch',
// Filter out CORS errors from third-party extensions
'cross-origin',
// Filter out client-side navigation cancellations
'cancelled navigation',
],
maxItems: 10, // Max items per page load
} : undefined;
import type { Dictionary } from 'rollbar';
export function isBot(userAgent: string | undefined) {
if (!userAgent) return false;
const botPatterns = [
'Googlebot', // Google
'Baiduspider', // Baidu
'bingbot', // Bing
'YandexBot', // Yandex
'DuckDuckBot', // DuckDuckGo
'Slurp', // Yahoo
'Applebot', // Apple
'facebookexternalhit', // Facebook
'Twitterbot', // Twitter
'rogerbot', // Moz
'Alexa', // Alexa
'AhrefsBot', // Ahrefs
'SemrushBot', // Semrush
'spider', // Generic spiders
'crawler', // Generic crawlers
];
return botPatterns.some(pattern =>
userAgent.toLowerCase().includes(pattern.toLowerCase()),
);
}
export function isHeadlessBrowser(userAgent: string | undefined) {
if (!userAgent) return false;
if (
userAgent.includes('headless') ||
userAgent.includes('phantomjs') ||
userAgent.includes('selenium') ||
userAgent.includes('puppeteer')
) {
return true;
}
}
export function isNextJsChunkError(url: unknown) {
if (typeof url !== 'string') return false;
return url.includes('/_next/');
}
export function getRequestInfo(item: Dictionary): { url: string } | undefined {
if (
!item.request ||
item.request === null ||
typeof item.request !== 'object' ||
!('url' in item.request) ||
typeof item.request.url !== 'string'
) {
return undefined;
}
return { url: item.request.url };
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment