Skip to content

Commit ae00784

Browse files
committed
ref(types): Tighten types for beforeSend & beforeSendTransaction
1 parent 09e1f22 commit ae00784

File tree

4 files changed

+57
-18
lines changed

4 files changed

+57
-18
lines changed

packages/core/src/baseclient.ts

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ import {
55
DataCategory,
66
DsnComponents,
77
Envelope,
8+
ErrorEvent,
89
Event,
910
EventDropReason,
1011
EventHint,
11-
EventType,
1212
Integration,
1313
IntegrationClass,
1414
Outcome,
1515
Session,
1616
SessionAggregates,
1717
Severity,
1818
SeverityLevel,
19+
TransactionEvent,
1920
Transport,
2021
} from '@sentry/types';
2122
import {
@@ -43,8 +44,6 @@ import { IntegrationIndex, setupIntegrations } from './integration';
4344
import { Scope } from './scope';
4445
import { updateSession } from './session';
4546

46-
type BeforeSendProcessorMethod = 'beforeSend' | 'beforeSendTransaction';
47-
4847
const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
4948

5049
/**
@@ -633,13 +632,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
633632
const isTransaction = event.type === 'transaction';
634633
const isError = !event.type;
635634

636-
const beforeSendProcessorMap: Map<EventType | undefined, BeforeSendProcessorMethod | undefined> = new Map([
637-
[undefined, 'beforeSend'],
638-
['transaction', 'beforeSendTransaction'],
639-
]);
640-
641-
const beforeSendProcessorName = beforeSendProcessorMap.get(event.type);
642-
const beforeSendProcessor = beforeSendProcessorName ? options[beforeSendProcessorName] : undefined;
635+
const beforeSendProcessorName = getBeforeSendMethodName(event);
643636

644637
// 1.0 === 100% events are sent
645638
// 0.0 === 0% events are sent
@@ -662,12 +655,12 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
662655
}
663656

664657
const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true;
665-
if (isInternalException || !beforeSendProcessor) {
658+
if (isInternalException) {
666659
return prepared;
667660
}
668661

669-
const beforeSendResult = beforeSendProcessor(prepared, hint);
670-
return _validateBeforeSendResult(beforeSendResult, beforeSendProcessorName as BeforeSendProcessorMethod);
662+
const beforeSendResult = processBeforeSend(options, prepared, hint);
663+
return _validateBeforeSendResult(beforeSendResult, beforeSendProcessorName);
671664
})
672665
.then(processedEvent => {
673666
if (processedEvent === null) {
@@ -789,7 +782,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
789782
*/
790783
function _validateBeforeSendResult(
791784
beforeSendResult: PromiseLike<Event | null> | Event | null,
792-
beforeSendProcessorName: 'beforeSend' | 'beforeSendTransaction',
785+
beforeSendProcessorName: string,
793786
): PromiseLike<Event | null> | Event | null {
794787
const invalidValueError = `\`${beforeSendProcessorName}\` must return \`null\` or a valid event.`;
795788
if (isThenable(beforeSendResult)) {
@@ -809,3 +802,46 @@ function _validateBeforeSendResult(
809802
}
810803
return beforeSendResult;
811804
}
805+
806+
/**
807+
* Process the matching `beforeSendXXX` callback.
808+
*/
809+
function processBeforeSend<T extends Event>(
810+
options: ClientOptions,
811+
event: T,
812+
hint: EventHint,
813+
): PromiseLike<T | null> | T | null {
814+
const { beforeSend, beforeSendTransaction } = options;
815+
816+
if (isErrorEvent(event) && beforeSend) {
817+
return beforeSend(event, hint) as PromiseLike<T | null> | T | null;
818+
}
819+
820+
if (isTransactionEvent(event) && beforeSendTransaction) {
821+
return beforeSendTransaction(event, hint) as PromiseLike<T | null> | T | null;
822+
}
823+
824+
return event;
825+
}
826+
827+
/** Get the name of the before send processor for logging purposes. */
828+
function getBeforeSendMethodName<T extends Event>(event: T): string {
829+
if (isErrorEvent(event)) {
830+
return 'beforeSend';
831+
}
832+
833+
if (isTransactionEvent(event)) {
834+
return 'beforeSendTransaction';
835+
}
836+
837+
// This shouldn't happen, but if it does, we need to return a string
838+
return 'unknown';
839+
}
840+
841+
function isErrorEvent(event: Event): event is ErrorEvent {
842+
return event.type === undefined;
843+
}
844+
845+
function isTransactionEvent(event: Event): event is TransactionEvent {
846+
return event.type === 'transaction';
847+
}

packages/types/src/event.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ export interface Event {
6161
/** JSDoc */
6262
export type EventType = 'transaction' | 'profile';
6363

64+
export type ErrorEvent = Event & { type: undefined };
65+
export type TransactionEvent = Event & { type: 'transaction' };
66+
6467
/** JSDoc */
6568
export interface EventHint {
6669
event_id?: string;

packages/types/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type {
2424
UserFeedbackItem,
2525
} from './envelope';
2626
export type { ExtendedError } from './error';
27-
export type { Event, EventHint, EventType } from './event';
27+
export type { Event, EventHint, ErrorEvent, TransactionEvent } from './event';
2828
export type { EventProcessor } from './eventprocessor';
2929
export type { Exception } from './exception';
3030
export type { Extra, Extras } from './extra';

packages/types/src/options.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Breadcrumb, BreadcrumbHint } from './breadcrumb';
2-
import { Event, EventHint } from './event';
2+
import { ErrorEvent, Event, EventHint, TransactionEvent } from './event';
33
import { Instrumenter } from './instrumenter';
44
import { Integration } from './integration';
55
import { CaptureContext } from './scope';
@@ -233,7 +233,7 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
233233
* @param hint Event metadata useful for processing.
234234
* @returns A new event that will be sent | null.
235235
*/
236-
beforeSend?: (event: Event, hint: EventHint) => PromiseLike<Event | null> | Event | null;
236+
beforeSend?: (event: ErrorEvent, hint: EventHint) => PromiseLike<Event | null> | Event | null;
237237

238238
/**
239239
* An event-processing callback for transaction events, guaranteed to be invoked after all other event
@@ -246,7 +246,7 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
246246
* @param hint Event metadata useful for processing.
247247
* @returns A new event that will be sent | null.
248248
*/
249-
beforeSendTransaction?: (event: Event, hint: EventHint) => PromiseLike<Event | null> | Event | null;
249+
beforeSendTransaction?: (event: TransactionEvent, hint: EventHint) => PromiseLike<Event | null> | Event | null;
250250

251251
/**
252252
* A callback invoked when adding a breadcrumb, allowing to optionally modify

0 commit comments

Comments
 (0)