85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import { createTransport } from '@sentry/core';
|
|
import type {
|
|
BaseTransportOptions,
|
|
Transport,
|
|
TransportMakeRequestResponse,
|
|
TransportRequest,
|
|
TransportRequestExecutor,
|
|
} from '@sentry/types';
|
|
import axios from 'axios';
|
|
import type { SentryState } from '../store/types';
|
|
import { sentryConfig, tokenHeader } from './constants';
|
|
import { convertRequestBody, generateToken, isExcludedPath } from './helpers';
|
|
import type { TransportProps } from './types';
|
|
|
|
const axiosInstance = axios.create();
|
|
|
|
axiosInstance.interceptors.request.use(config => {
|
|
// Блокируем отправку запросов для страниц из исключений, или если стоит флаг запрета отправки событий
|
|
if (isExcludedPath()) {
|
|
return Promise.reject(new Error('Request blocked due to excluded path.'));
|
|
}
|
|
|
|
return config;
|
|
});
|
|
|
|
/** Кастомный транспорт для отправки запросов в Sentry. */
|
|
const customTransport =
|
|
({ token, attempts, setState, renewToken }: TransportProps) =>
|
|
(options: BaseTransportOptions): Transport => {
|
|
const { enabledCustomHeaders, customHeaders, url, attemptsBeforeDisable, enabledCompressing, enabledEncoding, vector, msg } =
|
|
sentryConfig;
|
|
const makeRequest: TransportRequestExecutor = ({ body: data }) => {
|
|
const sendRequest = ({
|
|
body,
|
|
url: requestUrl,
|
|
}: Pick<BaseTransportOptions, 'url'> & TransportRequest): PromiseLike<TransportMakeRequestResponse> =>
|
|
new Promise((resolve, reject) => {
|
|
let newToken: SentryState['token'] = null;
|
|
|
|
if (renewToken) {
|
|
newToken = token ? generateToken(token) : null;
|
|
|
|
setState?.({ token: newToken });
|
|
}
|
|
|
|
axiosInstance
|
|
.post(requestUrl, convertRequestBody({ body, enabledCompressing, enabledEncoding, vector, msg }), {
|
|
headers: {
|
|
// Добавляем кастомные хедеры для запросов в Sentry
|
|
...(enabledCustomHeaders
|
|
? {
|
|
...(newToken ? { [tokenHeader]: newToken } : {}),
|
|
...customHeaders,
|
|
}
|
|
: {}),
|
|
},
|
|
})
|
|
.then(response => {
|
|
// При успешной отправке сбрасываем счётчик неудачных попыток
|
|
setState?.({ attempts: 0 });
|
|
|
|
resolve({
|
|
...response,
|
|
headers: response.headers as TransportMakeRequestResponse['headers'],
|
|
});
|
|
})
|
|
.catch(error => {
|
|
// Перезапрашиваем токен, если получили код 400 в ответ на отправку данных в Sentry
|
|
// и ещё не превышено допустимое количество попыток
|
|
if (error?.response?.status === 400 && attempts < attemptsBeforeDisable) {
|
|
renewToken?.();
|
|
}
|
|
|
|
reject(error);
|
|
});
|
|
});
|
|
|
|
return sendRequest({ body: data, url: url ?? options.url });
|
|
};
|
|
|
|
return createTransport(options, makeRequest);
|
|
};
|
|
|
|
export { customTransport };
|