Repository: getsentry/sentry
Pull request #87078: feat(outcomes): Add file type to 'too large' outcome.
Author: login: tobias-wilfert
Labels: name: Scope: Frontend
description: Automatically applied to PRs that change frontend components
Created: 2025-03-14T13:49:42Z | Merged: 2025-03-18T08:28:58Z

This PR attempts to add the necessary logic to show more detail for the 'too large' outcome.

Since I am not a front-end wizzard it might be that I am missing something though.

Relay PR: https://github.com/getsentry/relay/pull/4558
Fixes: https://github.com/getsentry/team-ingest/issues/635


Diff:
diff --git a/static/app/views/organizationStats/getReasonGroupName.spec.ts b/static/app/views/organizationStats/getReasonGroupName.spec.ts
new file mode 100644
index 00000000000000..ece7ebedf675a7
--- /dev/null
+++ b/static/app/views/organizationStats/getReasonGroupName.spec.ts
@@ -0,0 +1,69 @@
+import {Outcome} from 'sentry/types/core';
+
+import {ClientDiscardReason, getReasonGroupName} from './getReasonGroupName';
+
+describe('getReasonGroupName', function () {
+  it('handles legacy too_large reason', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large')).toBe('too_large');
+  });
+
+  it('handles all new too_large reasons', function () {
+    const testCases: Array<[string, string]> = [
+      ['too_large_unknown', 'too_large'],
+      ['too_large_event', 'too_large_event'],
+      ['too_large_transaction', 'too_large_transaction'],
+      ['too_large_security', 'too_large_security'],
+      ['too_large_attachment', 'too_large_attachment'],
+      ['too_large_form_data', 'too_large_form_data'],
+      ['too_large_raw_security', 'too_large_raw_security'],
+      ['too_large_nel', 'too_large_nel'],
+      ['too_large_unreal_report', 'too_large_unreal_report'],
+      ['too_large_user_report', 'too_large_user_report'],
+      ['too_large_session', 'too_large_session'],
+      ['too_large_sessions', 'too_large_sessions'],
+      ['too_large_statsd', 'too_large_statsd'],
+      ['too_large_metric_buckets', 'too_large_metric_buckets'],
+      ['too_large_client_report', 'too_large_client_report'],
+      ['too_large_profile', 'too_large_profile'],
+      ['too_large_replay_event', 'too_large_replay_event'],
+      ['too_large_replay_recording', 'too_large_replay_recording'],
+      ['too_large_replay_video', 'too_large_replay_video'],
+      ['too_large_check_in', 'too_large_check_in'],
+      ['too_large_otel_log', 'too_large_otel_log'],
+      ['too_large_log', 'too_large_log'],
+      ['too_large_span', 'too_large_span'],
+      ['too_large_otel_span', 'too_large_otel_span'],
+      ['too_large_otel_traces_data', 'too_large_otel_traces_data'],
+      ['too_large_user_report_v2', 'too_large_user_report_v2'],
+      ['too_large_profile_chunk', 'too_large_profile_chunk'],
+    ];
+
+    testCases.forEach(([input, expected]) => {
+      expect(getReasonGroupName(Outcome.INVALID, input)).toBe(expected);
+    });
+  });
+
+  it('handles unknown too_large reasons', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large_future_type')).toBe('internal');
+  });
+
+  it('handles other existing reason types', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'duplicate')).toBe('duplicate');
+    expect(getReasonGroupName(Outcome.INVALID, 'duplicate_item')).toBe('invalid_request');
+    expect(getReasonGroupName(Outcome.INVALID, 'project_id')).toBe('project_missing');
+    expect(getReasonGroupName(Outcome.INVALID, 'invalid_transaction')).toBe(
+      'invalid_data'
+    );
+
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'key_quota')).toBe('DSN limit');
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'org_quota')).toBe('global limit');
+
+    expect(getReasonGroupName(Outcome.FILTERED, 'browser-extensions')).toBe(
+      'Browser Extensions'
+    );
+
+    expect(getReasonGroupName(Outcome.CLIENT_DISCARD, 'queue_overflow')).toBe(
+      ClientDiscardReason.QUEUE_OVERFLOW
+    );
+  });
+});
diff --git a/static/app/views/organizationStats/getReasonGroupName.ts b/static/app/views/organizationStats/getReasonGroupName.ts
index 1dd43e0988af49..805e9fbda06996 100644
--- a/static/app/views/organizationStats/getReasonGroupName.ts
+++ b/static/app/views/organizationStats/getReasonGroupName.ts
@@ -24,7 +24,34 @@ enum DiscardReason {
   INVALID_REPLAY_VIDEO = 'invalid_replay_video',
   PAYLOAD = 'payload',
   INVALID_COMPRESSION = 'invalid_compression',
-  TOO_LARGE = 'too_large',
+  TOO_LARGE = 'too_large', // Left for backwards compatibility
+  TOO_LARGE_UNKNOWN = 'too_large_unknown',
+  TOO_LARGE_EVENT = 'too_large_event',
+  TOO_LARGE_TRANSACTION = 'too_large_transaction',
+  TOO_LARGE_SECURITY = 'too_large_security',
+  TOO_LARGE_ATTACHMENT = 'too_large_attachment',
+  TOO_LARGE_FORM_DATA = 'too_large_form_data',
+  TOO_LARGE_RAW_SECURITY = 'too_large_raw_security',
+  TOO_LARGE_NEL = 'too_large_nel',
+  TOO_LARGE_UNREAL_REPORT = 'too_large_unreal_report',
+  TOO_LARGE_USER_REPORT = 'too_large_user_report',
+  TOO_LARGE_SESSION = 'too_large_session',
+  TOO_LARGE_SESSIONS = 'too_large_sessions',
+  TOO_LARGE_STATSD = 'too_large_statsd',
+  TOO_LARGE_METRIC_BUCKETS = 'too_large_metric_buckets',
+  TOO_LARGE_CLIENT_REPORT = 'too_large_client_report',
+  TOO_LARGE_PROFILE = 'too_large_profile',
+  TOO_LARGE_REPLAY_EVENT = 'too_large_replay_event',
+  TOO_LARGE_REPLAY_RECORDING = 'too_large_replay_recording',
+  TOO_LARGE_REPLAY_VIDEO = 'too_large_replay_video',
+  TOO_LARGE_CHECK_IN = 'too_large_check_in',
+  TOO_LARGE_OTEL_LOG = 'too_large_otel_log',
+  TOO_LARGE_LOG = 'too_large_log',
+  TOO_LARGE_SPAN = 'too_large_span',
+  TOO_LARGE_OTEL_SPAN = 'too_large_otel_span',
+  TOO_LARGE_OTEL_TRACES_DATA = 'too_large_otel_traces_data',
+  TOO_LARGE_USER_REPORT_V2 = 'too_large_user_report_v2',
+  TOO_LARGE_PROFILE_CHUNK = 'too_large_profile_chunk',
   MISSING_MINIDUMP_UPLOAD = 'missing_minidump_upload',
   INVALID_MINIDUMP = 'invalid_minidump',
   SECURITY_REPORT = 'security_report',
@@ -44,7 +71,7 @@ enum DiscardReason {
 }
 
 // List of Client Discard Reason according to the Client Report's doc - https://develop.sentry.dev/sdk/client-reports/#envelope-item-payload
-enum ClientDiscardReason {
+export enum ClientDiscardReason {
   QUEUE_OVERFLOW = 'queue_overflow',
   CACHE_OVERFLOW = 'cache_overflow',
   RATELIMIT_BACKOFF = 'ratelimit_backoff',
@@ -91,7 +118,36 @@ const invalidReasonsGroup: Record<string, DiscardReason[]> = {
     DiscardReason.INVALID_REPLAY_VIDEO,
   ],
   payload: [DiscardReason.PAYLOAD, DiscardReason.INVALID_COMPRESSION],
-  too_large: [DiscardReason.TOO_LARGE],
+  too_large: [
+    DiscardReason.TOO_LARGE, // Left for backwards compatibility
+    DiscardReason.TOO_LARGE_UNKNOWN,
+  ],
+  too_large_event: [DiscardReason.TOO_LARGE_EVENT],
+  too_large_transaction: [DiscardReason.TOO_LARGE_TRANSACTION],
+  too_large_security: [DiscardReason.TOO_LARGE_SECURITY],
+  too_large_attachment: [DiscardReason.TOO_LARGE_ATTACHMENT],
+  too_large_form_data: [DiscardReason.TOO_LARGE_FORM_DATA],
+  too_large_raw_security: [DiscardReason.TOO_LARGE_RAW_SECURITY],
+  too_large_nel: [DiscardReason.TOO_LARGE_NEL],
+  too_large_unreal_report: [DiscardReason.TOO_LARGE_UNREAL_REPORT],
+  too_large_user_report: [DiscardReason.TOO_LARGE_USER_REPORT],
+  too_large_session: [DiscardReason.TOO_LARGE_SESSION],
+  too_large_sessions: [DiscardReason.TOO_LARGE_SESSIONS],
+  too_large_statsd: [DiscardReason.TOO_LARGE_STATSD],
+  too_large_metric_buckets: [DiscardReason.TOO_LARGE_METRIC_BUCKETS],
+  too_large_client_report: [DiscardReason.TOO_LARGE_CLIENT_REPORT],
+  too_large_profile: [DiscardReason.TOO_LARGE_PROFILE],
+  too_large_replay_event: [DiscardReason.TOO_LARGE_REPLAY_EVENT],
+  too_large_replay_recording: [DiscardReason.TOO_LARGE_REPLAY_RECORDING],
+  too_large_replay_video: [DiscardReason.TOO_LARGE_REPLAY_VIDEO],
+  too_large_check_in: [DiscardReason.TOO_LARGE_CHECK_IN],
+  too_large_otel_log: [DiscardReason.TOO_LARGE_OTEL_LOG],
+  too_large_log: [DiscardReason.TOO_LARGE_LOG],
+  too_large_span: [DiscardReason.TOO_LARGE_SPAN],
+  too_large_otel_span: [DiscardReason.TOO_LARGE_OTEL_SPAN],
+  too_large_otel_traces_data: [DiscardReason.TOO_LARGE_OTEL_TRACES_DATA],
+  too_large_user_report_v2: [DiscardReason.TOO_LARGE_USER_REPORT_V2],
+  too_large_profile_chunk: [DiscardReason.TOO_LARGE_PROFILE_CHUNK],
   minidump: [DiscardReason.MISSING_MINIDUMP_UPLOAD, DiscardReason.INVALID_MINIDUMP],
   security_report: [DiscardReason.SECURITY_REPORT, DiscardReason.SECURITY_REPORT_TYPE],
   unreal: [DiscardReason.PROCESS_UNREAL],


Reviews:
user: login: priscilawebdev
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T05:50:14Z
user: login: priscilawebdev
body: thanks for adding tests! it looks good to me 🙌
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T06:26:47Z
user: login: priscilawebdev
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-17T06:27:04Z
user: login: priscilawebdev
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T06:27:45Z
user: login: tobias-wilfert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T07:10:57Z

Review comments:
diff_hunk: @@ -0,0 +1,69 @@
+import {Outcome} from 'sentry/types/core';
+
+import {getReasonGroupName} from './getReasonGroupName';
+
+describe('getReasonGroupName', function () {
+  it('handles legacy too_large reason', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large')).toBe('too_large');
+  });
+
+  it('handles all new too_large reasons', function () {
+    const testCases: Array<[string, string]> = [
+      ['too_large_unknown', 'too_large'],
+      ['too_large_event', 'too_large_event'],
+      ['too_large_transaction', 'too_large_transaction'],
+      ['too_large_security', 'too_large_security'],
+      ['too_large_attachment', 'too_large_attachment'],
+      ['too_large_form_data', 'too_large_form_data'],
+      ['too_large_raw_security', 'too_large_raw_security'],
+      ['too_large_nel', 'too_large_nel'],
+      ['too_large_unreal_report', 'too_large_unreal_report'],
+      ['too_large_user_report', 'too_large_user_report'],
+      ['too_large_session', 'too_large_session'],
+      ['too_large_sessions', 'too_large_sessions'],
+      ['too_large_statsd', 'too_large_statsd'],
+      ['too_large_metric_buckets', 'too_large_metric_buckets'],
+      ['too_large_client_report', 'too_large_client_report'],
+      ['too_large_profile', 'too_large_profile'],
+      ['too_large_replay_event', 'too_large_replay_event'],
+      ['too_large_replay_recording', 'too_large_replay_recording'],
+      ['too_large_replay_video', 'too_large_replay_video'],
+      ['too_large_check_in', 'too_large_check_in'],
+      ['too_large_otel_log', 'too_large_otel_log'],
+      ['too_large_log', 'too_large_log'],
+      ['too_large_span', 'too_large_span'],
+      ['too_large_otel_span', 'too_large_otel_span'],
+      ['too_large_otel_traces_data', 'too_large_otel_traces_data'],
+      ['too_large_user_report_v2', 'too_large_user_report_v2'],
+      ['too_large_profile_chunk', 'too_large_profile_chunk'],
+    ];
+
+    testCases.forEach(([input, expected]) => {
+      expect(getReasonGroupName(Outcome.INVALID, input)).toBe(expected);
+    });
+  });
+
+  it('handles unknown too_large reasons', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large_future_type')).toBe('internal');
+  });
+
+  it('handles other existing reason types', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'duplicate')).toBe('duplicate');
+    expect(getReasonGroupName('invalid', 'duplicate_item')).toBe('invalid_request');
path: static/app/views/organizationStats/getReasonGroupName.spec.ts
user: login: priscilawebdev
body: ```suggestion
    expect(getReasonGroupName(Outcome.INVALID, 'duplicate_item')).toBe('invalid_request');
```
created_at: 2025-03-17T05:49:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,69 @@
+import {Outcome} from 'sentry/types/core';
+
+import {getReasonGroupName} from './getReasonGroupName';
+
+describe('getReasonGroupName', function () {
+  it('handles legacy too_large reason', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large')).toBe('too_large');
+  });
+
+  it('handles all new too_large reasons', function () {
+    const testCases: Array<[string, string]> = [
+      ['too_large_unknown', 'too_large'],
+      ['too_large_event', 'too_large_event'],
+      ['too_large_transaction', 'too_large_transaction'],
+      ['too_large_security', 'too_large_security'],
+      ['too_large_attachment', 'too_large_attachment'],
+      ['too_large_form_data', 'too_large_form_data'],
+      ['too_large_raw_security', 'too_large_raw_security'],
+      ['too_large_nel', 'too_large_nel'],
+      ['too_large_unreal_report', 'too_large_unreal_report'],
+      ['too_large_user_report', 'too_large_user_report'],
+      ['too_large_session', 'too_large_session'],
+      ['too_large_sessions', 'too_large_sessions'],
+      ['too_large_statsd', 'too_large_statsd'],
+      ['too_large_metric_buckets', 'too_large_metric_buckets'],
+      ['too_large_client_report', 'too_large_client_report'],
+      ['too_large_profile', 'too_large_profile'],
+      ['too_large_replay_event', 'too_large_replay_event'],
+      ['too_large_replay_recording', 'too_large_replay_recording'],
+      ['too_large_replay_video', 'too_large_replay_video'],
+      ['too_large_check_in', 'too_large_check_in'],
+      ['too_large_otel_log', 'too_large_otel_log'],
+      ['too_large_log', 'too_large_log'],
+      ['too_large_span', 'too_large_span'],
+      ['too_large_otel_span', 'too_large_otel_span'],
+      ['too_large_otel_traces_data', 'too_large_otel_traces_data'],
+      ['too_large_user_report_v2', 'too_large_user_report_v2'],
+      ['too_large_profile_chunk', 'too_large_profile_chunk'],
+    ];
+
+    testCases.forEach(([input, expected]) => {
+      expect(getReasonGroupName(Outcome.INVALID, input)).toBe(expected);
+    });
+  });
+
+  it('handles unknown too_large reasons', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large_future_type')).toBe('internal');
+  });
+
+  it('handles other existing reason types', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'duplicate')).toBe('duplicate');
+    expect(getReasonGroupName('invalid', 'duplicate_item')).toBe('invalid_request');
+    expect(getReasonGroupName(Outcome.INVALID, 'project_id')).toBe('project_missing');
+    expect(getReasonGroupName(Outcome.INVALID, 'invalid_transaction')).toBe(
+      'invalid_data'
+    );
+
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'key_quota')).toBe('DSN limit');
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'org_quota')).toBe('global limit');
+
+    expect(getReasonGroupName(Outcome.FILTERED, 'browser-extensions')).toBe(
+      'Browser Extensions'
+    );
+
+    expect(getReasonGroupName(Outcome.CLIENT_DISCARD, 'queue_overflow')).toBe(
path: static/app/views/organizationStats/getReasonGroupName.spec.ts
user: login: priscilawebdev
body: we could reuse the enum `ClientDiscardReason` here too 
created_at: 2025-03-17T05:51:06Z
author_association: MEMBER
diff_hunk: @@ -91,7 +118,37 @@ const invalidReasonsGroup: Record<string, DiscardReason[]> = {
     DiscardReason.INVALID_REPLAY_VIDEO,
   ],
   payload: [DiscardReason.PAYLOAD, DiscardReason.INVALID_COMPRESSION],
-  too_large: [DiscardReason.TOO_LARGE],
+  too_large: [
+    DiscardReason.TOO_LARGE, // Left for backwards compatibility
+    DiscardReason.TOO_LARGE_UNKNOWN,
+  ],
+  too_large_event: [DiscardReason.TOO_LARGE_EVENT],
+  too_large_transaction: [DiscardReason.TOO_LARGE_TRANSACTION],
+  too_large_security: [DiscardReason.TOO_LARGE_SECURITY],
+  too_large_attachment: [DiscardReason.TOO_LARGE_ATTACHMENT],
+  too_large_form_data: [DiscardReason.TOO_LARGE_FORM_DATA],
+  too_large_raw_security: [DiscardReason.TOO_LARGE_RAW_SECURITY],
+  too_large_nel: [DiscardReason.TOO_LARGE_NEL],
+  too_large_unreal_report: [DiscardReason.TOO_LARGE_UNREAL_REPORT],
+  too_large_user_report: [DiscardReason.TOO_LARGE_USER_REPORT],
+  too_large_session: [DiscardReason.TOO_LARGE_SESSION],
+  too_large_sessions: [DiscardReason.TOO_LARGE_SESSIONS],
+  too_large_statsd: [DiscardReason.TOO_LARGE_STATSD],
+  too_large_metric_buckets: [DiscardReason.TOO_LARGE_METRIC_BUCKETS],
+  too_large_client_report: [DiscardReason.TOO_LARGE_CLIENT_REPORT],
+  too_large_profile: [DiscardReason.TOO_LARGE_PROFILE],
+  too_large_replay_event: [DiscardReason.TOO_LARGE_REPLAY_EVENT],
+  too_large_replay_recording: [DiscardReason.TOO_LARGE_REPLAY_RECORDING],
+  too_large_replay_video: [DiscardReason.TOO_LARGE_REPLAY_VIDEO],
+  too_large_check_in: [DiscardReason.TOO_LARGE_CHECK_IN],
+  too_large_otel_log: [DiscardReason.TOO_LARGE_OTEL_LOG],
+  too_large_log: [DiscardReason.TOO_LARGE_LOG],
+  too_large_span: [DiscardReason.TOO_LARGE_SPAN],
+  too_large_otel_span: [DiscardReason.TOO_LARGE_OTEL_SPAN],
+  too_large_otel_traces_data: [DiscardReason.TOO_LARGE_OTEL_TRACES_DATA],
+  too_large_user_report_v2: [DiscardReason.TOO_LARGE_USER_REPORT_V2],
+  too_large_profile_chunk: [DiscardReason.TOO_LARGE_PROFILE_CHUNK],
+
path: static/app/views/organizationStats/getReasonGroupName.ts
user: login: priscilawebdev
body: ```suggestion
```
created_at: 2025-03-17T06:27:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,69 @@
+import {Outcome} from 'sentry/types/core';
+
+import {getReasonGroupName} from './getReasonGroupName';
+
+describe('getReasonGroupName', function () {
+  it('handles legacy too_large reason', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large')).toBe('too_large');
+  });
+
+  it('handles all new too_large reasons', function () {
+    const testCases: Array<[string, string]> = [
+      ['too_large_unknown', 'too_large'],
+      ['too_large_event', 'too_large_event'],
+      ['too_large_transaction', 'too_large_transaction'],
+      ['too_large_security', 'too_large_security'],
+      ['too_large_attachment', 'too_large_attachment'],
+      ['too_large_form_data', 'too_large_form_data'],
+      ['too_large_raw_security', 'too_large_raw_security'],
+      ['too_large_nel', 'too_large_nel'],
+      ['too_large_unreal_report', 'too_large_unreal_report'],
+      ['too_large_user_report', 'too_large_user_report'],
+      ['too_large_session', 'too_large_session'],
+      ['too_large_sessions', 'too_large_sessions'],
+      ['too_large_statsd', 'too_large_statsd'],
+      ['too_large_metric_buckets', 'too_large_metric_buckets'],
+      ['too_large_client_report', 'too_large_client_report'],
+      ['too_large_profile', 'too_large_profile'],
+      ['too_large_replay_event', 'too_large_replay_event'],
+      ['too_large_replay_recording', 'too_large_replay_recording'],
+      ['too_large_replay_video', 'too_large_replay_video'],
+      ['too_large_check_in', 'too_large_check_in'],
+      ['too_large_otel_log', 'too_large_otel_log'],
+      ['too_large_log', 'too_large_log'],
+      ['too_large_span', 'too_large_span'],
+      ['too_large_otel_span', 'too_large_otel_span'],
+      ['too_large_otel_traces_data', 'too_large_otel_traces_data'],
+      ['too_large_user_report_v2', 'too_large_user_report_v2'],
+      ['too_large_profile_chunk', 'too_large_profile_chunk'],
+    ];
+
+    testCases.forEach(([input, expected]) => {
+      expect(getReasonGroupName(Outcome.INVALID, input)).toBe(expected);
+    });
+  });
+
+  it('handles unknown too_large reasons', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'too_large_future_type')).toBe('internal');
+  });
+
+  it('handles other existing reason types', function () {
+    expect(getReasonGroupName(Outcome.INVALID, 'duplicate')).toBe('duplicate');
+    expect(getReasonGroupName('invalid', 'duplicate_item')).toBe('invalid_request');
+    expect(getReasonGroupName(Outcome.INVALID, 'project_id')).toBe('project_missing');
+    expect(getReasonGroupName(Outcome.INVALID, 'invalid_transaction')).toBe(
+      'invalid_data'
+    );
+
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'key_quota')).toBe('DSN limit');
+    expect(getReasonGroupName(Outcome.RATE_LIMITED, 'org_quota')).toBe('global limit');
+
+    expect(getReasonGroupName(Outcome.FILTERED, 'browser-extensions')).toBe(
+      'Browser Extensions'
+    );
+
+    expect(getReasonGroupName(Outcome.CLIENT_DISCARD, 'queue_overflow')).toBe(
path: static/app/views/organizationStats/getReasonGroupName.spec.ts
user: login: tobias-wilfert
body: Just to make sure I understand this correctly, I changed this to (which required to export the ClientDiscardReason) I hope this was what you meant:
```ts
expect(getReasonGroupName(Outcome.CLIENT_DISCARD, 'queue_overflow')).toBe(
  ClientDiscardReason.QUEUE_OVERFLOW
);
```
created_at: 2025-03-17T07:10:56Z
author_association: MEMBER

PR comments:
user: login: priscilawebdev
created_at: 2025-03-17T05:46:24Z
body: Please do not forget to update the doc with the exposed new reasons: https://docs.sentry.io/product/stats/#invalid 🙏
author_association: MEMBER
user: login: tobias-wilfert
created_at: 2025-03-17T11:23:18Z
body: > Please do not forget to update the doc with the exposed new reasons: https://docs.sentry.io/product/stats/#invalid 🙏

My attempt at updating the doc, feel free to leave comments on how it can be improved: https://github.com/getsentry/sentry-docs/pull/13012
author_association: MEMBER