Skip to content

Commit 514ef47

Browse files
committed
ref(replay): Extend ReplayLogger from core Logger
- Moved replay-specific `_serializeFormData` to `browser-utils` and added test. Signed-off-by: Kaung Zin Hein <83657429+Zen-cronic@users.noreply.github.com>
1 parent 200d810 commit 514ef47

File tree

5 files changed

+32
-56
lines changed

5 files changed

+32
-56
lines changed

packages/browser-utils/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ export { fetch, setTimeout, clearCachedImplementation, getNativeImplementation }
2727

2828
export { addXhrInstrumentationHandler, SENTRY_XHR_DATA_KEY } from './instrument/xhr';
2929

30-
export { getBodyString, getFetchRequestArgBody } from './networkUtils';
30+
export { getBodyString, getFetchRequestArgBody, serializeFormData } from './networkUtils';
3131

3232
export type { FetchHint, NetworkMetaWarning, XhrHint } from './types';

packages/browser-utils/src/networkUtils.ts

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,22 @@
1-
import type { ConsoleLevel, Logger } from '@sentry/core';
1+
import { logger } from '@sentry/core';
2+
import type { Logger } from '@sentry/core';
23
import { DEBUG_BUILD } from './debug-build';
34
import type { NetworkMetaWarning } from './types';
45

5-
type ReplayConsoleLevels = Extract<ConsoleLevel, 'info' | 'warn' | 'error' | 'log'>;
6-
type LoggerMethod = (...args: unknown[]) => void;
7-
type LoggerConsoleMethods = Record<ReplayConsoleLevels, LoggerMethod>;
8-
9-
interface LoggerConfig {
10-
captureExceptions: boolean;
11-
traceInternals: boolean;
12-
}
13-
14-
// Duplicate from replay-internal
15-
interface ReplayLogger extends LoggerConsoleMethods {
16-
/**
17-
* Calls `logger.info` but saves breadcrumb in the next tick due to race
18-
* conditions before replay is initialized.
19-
*/
20-
infoTick: LoggerMethod;
21-
/**
22-
* Captures exceptions (`Error`) if "capture internal exceptions" is enabled
23-
*/
24-
exception: LoggerMethod;
25-
/**
26-
* Configures the logger with additional debugging behavior
27-
*/
28-
setConfig(config: Partial<LoggerConfig>): void;
29-
}
30-
31-
function _serializeFormData(formData: FormData): string {
32-
// This is a bit simplified, but gives us a decent estimate
33-
// This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'
6+
/**
7+
* Serializes FormData.
8+
*
9+
* This is a bit simplified, but gives us a decent estimate.
10+
* This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'.
11+
*
12+
*/
13+
export function serializeFormData(formData: FormData): string {
3414
// @ts-expect-error passing FormData to URLSearchParams actually works
3515
return new URLSearchParams(formData).toString();
3616
}
3717

3818
/** Get the string representation of a body. */
39-
export function getBodyString(
40-
body: unknown,
41-
logger?: Logger | ReplayLogger,
42-
): [string | undefined, NetworkMetaWarning?] {
19+
export function getBodyString(body: unknown, _logger: Logger = logger): [string | undefined, NetworkMetaWarning?] {
4320
try {
4421
if (typeof body === 'string') {
4522
return [body];
@@ -50,23 +27,18 @@ export function getBodyString(
5027
}
5128

5229
if (body instanceof FormData) {
53-
return [_serializeFormData(body)];
30+
return [serializeFormData(body)];
5431
}
5532

5633
if (!body) {
5734
return [undefined];
5835
}
5936
} catch (error) {
60-
// RelayLogger
61-
if (DEBUG_BUILD && logger && 'exception' in logger) {
62-
logger.exception(error, 'Failed to serialize body', body);
63-
} else if (DEBUG_BUILD && logger) {
64-
logger.error(error, 'Failed to serialize body', body);
65-
}
37+
DEBUG_BUILD && logger.error(error, 'Failed to serialize body', body);
6638
return [undefined, 'BODY_PARSE_ERROR'];
6739
}
6840

69-
DEBUG_BUILD && logger?.info('Skipping network body because of body type', body);
41+
DEBUG_BUILD && logger.info('Skipping network body because of body type', body);
7042

7143
return [undefined, 'UNPARSEABLE_BODY_TYPE'];
7244
}

packages/browser-utils/test/networkUtils.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
import { describe, expect, it } from 'vitest';
6-
import { getBodyString, getFetchRequestArgBody } from '../src/networkUtils';
6+
import { getBodyString, getFetchRequestArgBody, serializeFormData } from '../src/networkUtils';
77

88
describe('getBodyString', () => {
99
it('should work with a string', () => {
@@ -94,3 +94,14 @@ describe('getFetchRequestArgBody', () => {
9494
});
9595
});
9696
});
97+
98+
describe('serializeFormData', () => {
99+
it('works with FormData', () => {
100+
const formData = new FormData();
101+
formData.append('name', 'Anne Smith');
102+
formData.append('age', '13');
103+
104+
const actual = serializeFormData(formData);
105+
expect(actual).toBe('name=Anne+Smith&age=13');
106+
});
107+
});

packages/replay-internal/src/coreHandlers/util/networkUtils.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { serializeFormData } from '@sentry-internal/browser-utils';
2+
import type { NetworkMetaWarning } from '@sentry-internal/browser-utils';
13
import { dropUndefinedKeys, stringMatchesSomePattern } from '@sentry/core';
24

3-
import type { NetworkMetaWarning } from '@sentry-internal/browser-utils';
45
import { NETWORK_BODY_MAX_SIZE, WINDOW } from '../../constants';
56
import type {
67
NetworkBody,
@@ -28,7 +29,7 @@ export function getBodySize(body: RequestInit['body']): number | undefined {
2829
}
2930

3031
if (body instanceof FormData) {
31-
const formDataStr = _serializeFormData(body);
32+
const formDataStr = serializeFormData(body);
3233
return textEncoder.encode(formDataStr).length;
3334
}
3435

@@ -170,13 +171,6 @@ export function getAllowedHeaders(headers: Record<string, string>, allowedHeader
170171
}, {});
171172
}
172173

173-
function _serializeFormData(formData: FormData): string {
174-
// This is a bit simplified, but gives us a decent estimate
175-
// This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'
176-
// @ts-expect-error passing FormData to URLSearchParams actually works
177-
return new URLSearchParams(formData).toString();
178-
}
179-
180174
function normalizeNetworkBody(body: string | undefined): {
181175
body: NetworkBody | undefined;
182176
warnings?: NetworkMetaWarning[];

packages/replay-internal/src/util/logger.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ConsoleLevel, SeverityLevel } from '@sentry/core';
1+
import type { ConsoleLevel, Logger, SeverityLevel } from '@sentry/core';
22
import { addBreadcrumb, captureException, logger as coreLogger, severityLevelFromString } from '@sentry/core';
33
import { DEBUG_BUILD } from '../debug-build';
44

@@ -7,14 +7,13 @@ const CONSOLE_LEVELS: readonly ReplayConsoleLevels[] = ['info', 'warn', 'error',
77
const PREFIX = '[Replay] ';
88

99
type LoggerMethod = (...args: unknown[]) => void;
10-
type LoggerConsoleMethods = Record<ReplayConsoleLevels, LoggerMethod>;
1110

1211
interface LoggerConfig {
1312
captureExceptions: boolean;
1413
traceInternals: boolean;
1514
}
1615

17-
interface ReplayLogger extends LoggerConsoleMethods {
16+
interface ReplayLogger extends Logger {
1817
/**
1918
* Calls `logger.info` but saves breadcrumb in the next tick due to race
2019
* conditions before replay is initialized.

0 commit comments

Comments
 (0)