From 64dda8c1112c1f823b5ad07feedcb44d64b2546c Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Wed, 2 Sep 2026 12:57:15 +0000 Subject: [PATCH] refactor: migrate from @sentry/minimal to @sentry/node for improved error handling --- backend/package.json | 1 - .../authorization/auth-with-api.middleware.ts | 68 +++++++++---------- backend/src/authorization/auth.middleware.ts | 7 +- .../non-scoped-auth.middleware.ts | 4 +- .../public-or-auth.middleware.ts | 4 +- .../temporary-auth.middleware.ts | 4 +- ...-settings-and-widgets-creation.use.case.ts | 2 +- ...est-info-from-table-with-ai-v7.use.case.ts | 2 +- .../entities/cron-jobs/cron-jobs.service.ts | 2 +- .../generate-schema-change.use-case.ts | 2 +- .../use-cases/get-table-rows.use.case.ts | 2 +- ...sers-actions-and-mailing-users.use.case.ts | 2 +- .../src/exceptions/all-exceptions.filter.ts | 33 ++++++--- .../src/helpers/slack/slack-post-message.ts | 2 +- .../src/interceptors/sentry.interceptor.ts | 38 +++-------- backend/src/main.ts | 20 ++++-- .../scan-and-create-settings.use.case.ts | 2 +- .../use-cases/validate-user-token.use.case.ts | 2 +- pnpm-lock.yaml | 43 ------------ 19 files changed, 101 insertions(+), 139 deletions(-) diff --git a/backend/package.json b/backend/package.json index bbdaddcd3..6103ba23b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -48,7 +48,6 @@ "@nestjs/throttler": "^6.5.0", "@nestjs/typeorm": "^11.0.1", "@rocketadmin/shared-code": "workspace:*", - "@sentry/minimal": "^6.19.7", "@sentry/node": "10.53.1", "@toon-format/toon": "^2.3.0", "@types/crypto-js": "^4.2.2", diff --git a/backend/src/authorization/auth-with-api.middleware.ts b/backend/src/authorization/auth-with-api.middleware.ts index c2b9113db..3dfb1ce1b 100644 --- a/backend/src/authorization/auth-with-api.middleware.ts +++ b/backend/src/authorization/auth-with-api.middleware.ts @@ -7,7 +7,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; @@ -34,7 +34,10 @@ export class AuthWithApiMiddleware implements NestMiddleware { await this.authenticateRequest(req); next(); } catch (error) { - Sentry.captureException(error); + // Capture only what becomes a 500 (plan 30) — see handleAuthenticationError's mapping. + if (!(error instanceof HttpException || error instanceof UnauthorizedException)) { + Sentry.captureException(error); + } this.handleAuthenticationError(error); } } @@ -60,44 +63,41 @@ export class AuthWithApiMiddleware implements NestMiddleware { } private async authenticateWithToken(tokenFromCookie: string, req: IRequestWithCognitoInfo): Promise { - try { - const jwtSecret = appConfig.auth.jwtSecret; - if (!jwtSecret) { - throw new UnauthorizedException('JWT verification failed'); - } - const data = jwt.verify(tokenFromCookie, jwtSecret) as jwt.JwtPayload; - const userId = data.id; + // No try/catch here (plan 30): the caller's catch owns both the Sentry capture and the + // error mapping — the old inner capture double-reported every failure. + const jwtSecret = appConfig.auth.jwtSecret; + if (!jwtSecret) { + throw new UnauthorizedException('JWT verification failed'); + } + const data = jwt.verify(tokenFromCookie, jwtSecret) as jwt.JwtPayload; + const userId = data.id; - if (!userId) { - throw new UnauthorizedException('JWT verification failed'); - } + if (!userId) { + throw new UnauthorizedException('JWT verification failed'); + } - const userExists = await this.userRepository.findOne({ where: { id: userId } }); - if (!userExists) { - throw new UnauthorizedException('JWT verification failed'); - } + const userExists = await this.userRepository.findOne({ where: { id: userId } }); + if (!userExists) { + throw new UnauthorizedException('JWT verification failed'); + } - if (userExists.suspended) { - throw new UnauthorizedException(Messages.ACCOUNT_SUSPENDED); - } + if (userExists.suspended) { + throw new UnauthorizedException(Messages.ACCOUNT_SUSPENDED); + } - assertTokenScopeAllowed(data.scope as Array); + assertTokenScopeAllowed(data.scope as Array); - const payload = { - sub: userId, - email: data.email, - companyId: data.companyId ?? null, - exp: data.exp, - iat: data.iat, - }; - if (!payload || isObjectEmpty(payload)) { - throw new UnauthorizedException('JWT verification failed'); - } - req.decoded = payload; - } catch (error) { - Sentry.captureException(error); - throw error; + const payload = { + sub: userId, + email: data.email, + companyId: data.companyId ?? null, + exp: data.exp, + iat: data.iat, + }; + if (!payload || isObjectEmpty(payload)) { + throw new UnauthorizedException('JWT verification failed'); } + req.decoded = payload; } private async authenticateWithApiKey(req: IRequestWithCognitoInfo): Promise { diff --git a/backend/src/authorization/auth.middleware.ts b/backend/src/authorization/auth.middleware.ts index 8a1f7eea1..5255dc25f 100644 --- a/backend/src/authorization/auth.middleware.ts +++ b/backend/src/authorization/auth.middleware.ts @@ -6,7 +6,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; @@ -84,10 +84,13 @@ export class AuthMiddleware implements NestMiddleware { req.decoded = payload; next(); } catch (e) { - Sentry.captureException(e); if (e instanceof HttpException || e instanceof UnauthorizedException) { throw e; } + // Capture only what becomes a 500 (plan 30): expected auth verdicts (401/403 HttpExceptions) + // are outcomes, not incidents. These captures were silently dropped for as long as the + // dead @sentry/minimal import was in place; now that they are live again, gate the noise. + Sentry.captureException(e); throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); } } diff --git a/backend/src/authorization/non-scoped-auth.middleware.ts b/backend/src/authorization/non-scoped-auth.middleware.ts index 8dcb6b33a..67887ae30 100644 --- a/backend/src/authorization/non-scoped-auth.middleware.ts +++ b/backend/src/authorization/non-scoped-auth.middleware.ts @@ -6,7 +6,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; @@ -68,10 +68,10 @@ export class NonScopedAuthMiddleware implements NestMiddleware { req.decoded = payload; next(); } catch (e) { - Sentry.captureException(e); if (e instanceof HttpException || e instanceof UnauthorizedException) { throw e; } + Sentry.captureException(e); throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); } } diff --git a/backend/src/authorization/public-or-auth.middleware.ts b/backend/src/authorization/public-or-auth.middleware.ts index 5d66ee01f..3d2071794 100644 --- a/backend/src/authorization/public-or-auth.middleware.ts +++ b/backend/src/authorization/public-or-auth.middleware.ts @@ -7,7 +7,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; @@ -57,10 +57,10 @@ export class PublicOrAuthMiddleware implements NestMiddleware { } next(); } catch (error) { - Sentry.captureException(error); if (error instanceof HttpException || error instanceof UnauthorizedException) { throw error; } + Sentry.captureException(error); throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); } } diff --git a/backend/src/authorization/temporary-auth.middleware.ts b/backend/src/authorization/temporary-auth.middleware.ts index 1de4fe590..d0853c6d3 100644 --- a/backend/src/authorization/temporary-auth.middleware.ts +++ b/backend/src/authorization/temporary-auth.middleware.ts @@ -6,7 +6,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; @@ -68,10 +68,10 @@ export class TemporaryAuthMiddleware implements NestMiddleware { req.decoded = payload; next(); } catch (e) { - Sentry.captureException(e); if (e instanceof HttpException || e instanceof UnauthorizedException) { throw e; } + Sentry.captureException(e); throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); } } diff --git a/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts index 2165efa38..4cf7ddaed 100644 --- a/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts @@ -1,5 +1,5 @@ import { HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { Response } from 'express'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; diff --git a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts index 7722752b9..18cdbb6a5 100644 --- a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts @@ -4,7 +4,7 @@ import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-acce import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { Response } from 'express'; import { AIToolCall, AIToolDefinition } from '../../../ai-core/interfaces/ai-provider.interface.js'; import { AIProviderType } from '../../../ai-core/interfaces/ai-service.interface.js'; diff --git a/backend/src/entities/cron-jobs/cron-jobs.service.ts b/backend/src/entities/cron-jobs/cron-jobs.service.ts index f667dd84c..4eda5883f 100644 --- a/backend/src/entities/cron-jobs/cron-jobs.service.ts +++ b/backend/src/entities/cron-jobs/cron-jobs.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { Repository } from 'typeorm'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { Constants } from '../../helpers/constants/constants.js'; diff --git a/backend/src/entities/table-schema/use-cases/generate-schema-change.use-case.ts b/backend/src/entities/table-schema/use-cases/generate-schema-change.use-case.ts index f7aeddae1..f6b7cb53e 100644 --- a/backend/src/entities/table-schema/use-cases/generate-schema-change.use-case.ts +++ b/backend/src/entities/table-schema/use-cases/generate-schema-change.use-case.ts @@ -2,7 +2,7 @@ import { BaseMessage } from '@langchain/core/messages'; import { BadRequestException, HttpStatus, Inject, Injectable, Logger, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import crypto from 'crypto'; import { AIProviderType } from '../../../ai-core/interfaces/ai-service.interface.js'; import { AICoreService } from '../../../ai-core/services/ai-core.service.js'; diff --git a/backend/src/entities/table/use-cases/get-table-rows.use.case.ts b/backend/src/entities/table/use-cases/get-table-rows.use.case.ts index 48e1e86d9..6bd628ef7 100644 --- a/backend/src/entities/table/use-cases/get-table-rows.use.case.ts +++ b/backend/src/entities/table/use-cases/get-table-rows.use.case.ts @@ -8,7 +8,7 @@ import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/en import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import { FoundRowsDS } from '@rocketadmin/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.js'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; diff --git a/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts b/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts index 124a99c43..bde1723ac 100644 --- a/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts +++ b/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import PQueue from 'p-queue'; import { Repository } from 'typeorm'; import { UserActionEnum } from '../../../enums/user-action.enum.js'; diff --git a/backend/src/exceptions/all-exceptions.filter.ts b/backend/src/exceptions/all-exceptions.filter.ts index 470cd1f20..45eecc4ee 100644 --- a/backend/src/exceptions/all-exceptions.filter.ts +++ b/backend/src/exceptions/all-exceptions.filter.ts @@ -1,5 +1,5 @@ import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from '@nestjs/common'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { WinstonLogger } from '../entities/logging/winston-logger.js'; import { getErrorMessage } from '../helpers/get-error-message.js'; import { ExceptionType } from './custom-exceptions/exception-type.js'; @@ -38,15 +38,28 @@ export class AllExceptionsFilter implements ExceptionFilter { const originalMessage = meta.originalMessage; const internalCode = meta.internalCode; const status = effective instanceof HttpException ? effective.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR; - const sentryContextObject = { - extra: { - original_exception_message: originalMessage, - message_to_user: text ? text : 'Something went wrong', - path: request.url, - exception_status_code: status, - }, - }; - Sentry.captureException(exception, sentryContextObject); + + if (status >= 500 || status === 408 || !(effective instanceof HttpException)) { + const requestId = request.headers?.['x-request-id']; + const generationId = request.headers?.['x-generation-id']; + const userEmail = request.decoded?.email; + Sentry.withScope((scope) => { + if (typeof requestId === 'string' && requestId !== '') { + scope.setTag('requestId', requestId); + } + if (typeof generationId === 'string' && generationId !== '') { + scope.setTag('generationId', generationId); + } + scope.setExtras({ + original_exception_message: originalMessage, + message_to_user: text ? text : 'Something went wrong', + path: request.url, + exception_status_code: status, + user_email: userEmail ?? 'unknown', + }); + Sentry.captureException(exception); + }); + } if (status === 500 || status === 408) { this.logger.error(exception); diff --git a/backend/src/helpers/slack/slack-post-message.ts b/backend/src/helpers/slack/slack-post-message.ts index 1005b1058..3b367146b 100644 --- a/backend/src/helpers/slack/slack-post-message.ts +++ b/backend/src/helpers/slack/slack-post-message.ts @@ -1,4 +1,4 @@ -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import axios from 'axios'; import { appConfig } from '../../shared/config/app-config.js'; import { Constants } from '../constants/constants.js'; diff --git a/backend/src/interceptors/sentry.interceptor.ts b/backend/src/interceptors/sentry.interceptor.ts index b4c5b8946..b1f426abc 100644 --- a/backend/src/interceptors/sentry.interceptor.ts +++ b/backend/src/interceptors/sentry.interceptor.ts @@ -1,36 +1,16 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; -import Sentry from '@sentry/minimal'; import { Observable } from 'rxjs'; -import { tap } from 'rxjs/operators'; +// Passthrough since plan 30. This interceptor used to capture every exception on its controllers +// itself — through the deprecated @sentry/minimal v6 API, whose hub the @sentry/node v10 client +// never wires, so those captures were silently dropped for as long as both packages coexisted — +// and each error was ALSO captured by the global AllExceptionsFilter, which sees every exception +// on every route. The filter is now the single (working) capture point, with the request context +// attached inside a per-event scope. The class stays so the existing +// @UseInterceptors(SentryInterceptor) decorators keep compiling; remove them at leisure. @Injectable() export class SentryInterceptor implements NestInterceptor { - async intercept(context: ExecutionContext, next: CallHandler): Promise> { - try { - const contextArgs = context.getArgs(); - const userEmail = contextArgs[0]?.decoded?.email; - const receivedConnectionHost = contextArgs[0]?.body?.host; - return next.handle().pipe( - tap(null, async (exception) => { - Sentry.setContext('user_email', { - email: userEmail ? userEmail : 'unknown', - }); - if (receivedConnectionHost) { - Sentry.setContext('received_connection_hostname', { - hostname: receivedConnectionHost, - }); - } - if (exception.originalMessage) { - Sentry.setContext('original_exception_message', { - originalMessage: exception.originalMessage, - }); - } - Sentry.captureException(exception); - }), - ); - } catch (e) { - console.error(e); - return next.handle(); - } + intercept(_context: ExecutionContext, next: CallHandler): Observable { + return next.handle(); } } diff --git a/backend/src/main.ts b/backend/src/main.ts index da6aae6cb..79155ad4e 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -18,6 +18,21 @@ import { appConfig } from './shared/config/app-config.js'; async function bootstrap() { try { appConfig.validate(); + // Before the app is built: Sentry's default integrations install the process-level + // uncaughtException / unhandledRejection handlers, so initializing after NestFactory.create + // left every module-init and DB-connect failure on the floor. A blank/unset DSN keeps every + // capture call a no-op. + Sentry.init({ + dsn: appConfig.thirdParty.sentryDsn ?? undefined, + // Separates prod/staging/dev events; unset shows as Sentry's default. + environment: process.env.SENTRY_ENVIRONMENT, + // Was a hard-coded 1.0 — 100% performance tracing in prod is a cost bug, and errors + // are captured regardless of this rate. Same env knob + default as agents-core/saas. + // NOTE: with the init here (after express/typeorm are loaded), a nonzero rate yields + // few real traces — enabling tracing for real needs a `node --import` preload init + // (see plan 30's rolled-back addendum). + tracesSampleRate: Number(process.env.SENTRY_TRACES_SAMPLE_RATE ?? 0) || 0, + }); const appOptions: NestApplicationOptions = { rawBody: true, logger: new WinstonLogger(), @@ -27,11 +42,6 @@ async function bootstrap() { app.useLogger(app.get(WinstonLogger)); app.set('query parser', 'extended'); - Sentry.init({ - dsn: appConfig.thirdParty.sentryDsn ?? undefined, - tracesSampleRate: 1.0, - }); - const globalPrefix = appConfig.app.globalPrefix; app.setGlobalPrefix(globalPrefix); diff --git a/backend/src/microservices/agents-microservice/use-cases/scan-and-create-settings.use.case.ts b/backend/src/microservices/agents-microservice/use-cases/scan-and-create-settings.use.case.ts index 5ca494a63..1bd52f914 100644 --- a/backend/src/microservices/agents-microservice/use-cases/scan-and-create-settings.use.case.ts +++ b/backend/src/microservices/agents-microservice/use-cases/scan-and-create-settings.use.case.ts @@ -1,5 +1,5 @@ import { HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import { Response } from 'express'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; diff --git a/backend/src/microservices/agents-microservice/use-cases/validate-user-token.use.case.ts b/backend/src/microservices/agents-microservice/use-cases/validate-user-token.use.case.ts index 7e0eddb41..f73784f79 100644 --- a/backend/src/microservices/agents-microservice/use-cases/validate-user-token.use.case.ts +++ b/backend/src/microservices/agents-microservice/use-cases/validate-user-token.use.case.ts @@ -1,5 +1,5 @@ import { HttpException, Inject, Injectable, Scope, UnauthorizedException } from '@nestjs/common'; -import Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/node'; import jwt from 'jsonwebtoken'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e46ada084..144f7ad5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -104,9 +104,6 @@ importers: '@rocketadmin/shared-code': specifier: workspace:* version: link:../shared-code - '@sentry/minimal': - specifier: ^6.19.7 - version: 6.19.7 '@sentry/node': specifier: 10.53.1 version: 10.53.1 @@ -2037,14 +2034,6 @@ packages: resolution: {integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==} engines: {node: '>=18'} - '@sentry/hub@6.19.7': - resolution: {integrity: sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==} - engines: {node: '>=6'} - - '@sentry/minimal@6.19.7': - resolution: {integrity: sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==} - engines: {node: '>=6'} - '@sentry/node-core@10.53.1': resolution: {integrity: sha512-iH7SMcM/7jPbN+t7+7ussQOiIqI4BMOGt4VYWlV71/z7k0pY+YPaSvlfVkNXfISiDzFAKv0ecCY3BmsLMu1xDQ==} engines: {node: '>=18'} @@ -2082,14 +2071,6 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 '@opentelemetry/semantic-conventions': ^1.39.0 - '@sentry/types@6.19.7': - resolution: {integrity: sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==} - engines: {node: '>=6'} - - '@sentry/utils@6.19.7': - resolution: {integrity: sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==} - engines: {node: '>=6'} - '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} @@ -5277,9 +5258,6 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -7731,18 +7709,6 @@ snapshots: '@sentry/core@10.53.1': {} - '@sentry/hub@6.19.7': - dependencies: - '@sentry/types': 6.19.7 - '@sentry/utils': 6.19.7 - tslib: 1.14.1 - - '@sentry/minimal@6.19.7': - dependencies: - '@sentry/hub': 6.19.7 - '@sentry/types': 6.19.7 - tslib: 1.14.1 - '@sentry/node-core@10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.0(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.0(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0)': dependencies: '@sentry/core': 10.53.1 @@ -7798,13 +7764,6 @@ snapshots: '@opentelemetry/semantic-conventions': 1.40.0 '@sentry/core': 10.53.1 - '@sentry/types@6.19.7': {} - - '@sentry/utils@6.19.7': - dependencies: - '@sentry/types': 6.19.7 - tslib: 1.14.1 - '@sindresorhus/merge-streams@4.0.0': {} '@smithy/config-resolver@4.4.17': @@ -11274,8 +11233,6 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@1.14.1: {} - tslib@2.8.1: {} tunnel-ssh@5.2.0: