Skip to content

Commit 30cadf9

Browse files
authored
ref(deno): Remove @sentry/browser dependency from @sentry/deno (#10867)
Adds the breadcrumbsIntegration (without xhr, dom, history) to deno without importing that from browser.
1 parent 652b621 commit 30cadf9

File tree

4 files changed

+180
-10
lines changed

4 files changed

+180
-10
lines changed

packages/deno/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
},
1414
"files": ["index.mjs", "index.mjs.map", "index.d.ts"],
1515
"dependencies": {
16-
"@sentry/browser": "8.0.0-alpha.0",
1716
"@sentry/core": "8.0.0-alpha.0",
1817
"@sentry/types": "8.0.0-alpha.0",
1918
"@sentry/utils": "8.0.0-alpha.0"

packages/deno/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ export {
9595
init,
9696
} from './sdk';
9797

98-
export { breadcrumbsIntegration } from '@sentry/browser';
9998
import { Integrations as CoreIntegrations } from '@sentry/core';
10099

101100
export { denoContextIntegration } from './integrations/context';
102101
export { globalHandlersIntegration } from './integrations/globalhandlers';
103102
export { normalizePathsIntegration } from './integrations/normalizepaths';
104103
export { contextLinesIntegration } from './integrations/contextlines';
105104
export { denoCronIntegration } from './integrations/deno-cron';
105+
export { breadcrumbsIntegration } from './integrations/breadcrumbs';
106106

107107
import * as DenoIntegrations from './integrations';
108108

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core';
2+
import type { Client, Event as SentryEvent, HandlerDataConsole, HandlerDataFetch, IntegrationFn } from '@sentry/types';
3+
import type { FetchBreadcrumbData, FetchBreadcrumbHint } from '@sentry/types/build/types/breadcrumb';
4+
import {
5+
addConsoleInstrumentationHandler,
6+
addFetchInstrumentationHandler,
7+
getEventDescription,
8+
safeJoin,
9+
severityLevelFromString,
10+
} from '@sentry/utils';
11+
12+
interface BreadcrumbsOptions {
13+
console: boolean;
14+
fetch: boolean;
15+
sentry: boolean;
16+
}
17+
18+
const INTEGRATION_NAME = 'Breadcrumbs';
19+
20+
const _breadcrumbsIntegration = ((options: Partial<BreadcrumbsOptions> = {}) => {
21+
const _options = {
22+
console: true,
23+
fetch: true,
24+
sentry: true,
25+
...options,
26+
};
27+
28+
return {
29+
name: INTEGRATION_NAME,
30+
setup(client) {
31+
if (_options.console) {
32+
addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));
33+
}
34+
if (_options.fetch) {
35+
addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));
36+
}
37+
if (_options.sentry) {
38+
client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));
39+
}
40+
},
41+
};
42+
}) satisfies IntegrationFn;
43+
44+
/**
45+
* This breadcrumbsIntegration is almost the same as the one from @sentry/browser.
46+
* The Deno-version does not support browser-specific APIs like dom, xhr and history.
47+
*/
48+
export const breadcrumbsIntegration = defineIntegration(_breadcrumbsIntegration);
49+
50+
/**
51+
* Adds a breadcrumb for Sentry events or transactions if this option is enabled.
52+
*
53+
*/
54+
function _getSentryBreadcrumbHandler(client: Client): (event: SentryEvent) => void {
55+
return function addSentryBreadcrumb(event: SentryEvent): void {
56+
if (getClient() !== client) {
57+
return;
58+
}
59+
60+
addBreadcrumb(
61+
{
62+
category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,
63+
event_id: event.event_id,
64+
level: event.level,
65+
message: getEventDescription(event),
66+
},
67+
{
68+
event,
69+
},
70+
);
71+
};
72+
}
73+
74+
/**
75+
* Creates breadcrumbs from console API calls
76+
*/
77+
function _getConsoleBreadcrumbHandler(client: Client): (handlerData: HandlerDataConsole) => void {
78+
return function _consoleBreadcrumb(handlerData: HandlerDataConsole): void {
79+
if (getClient() !== client) {
80+
return;
81+
}
82+
83+
const breadcrumb = {
84+
category: 'console',
85+
data: {
86+
arguments: handlerData.args,
87+
logger: 'console',
88+
},
89+
level: severityLevelFromString(handlerData.level),
90+
message: safeJoin(handlerData.args, ' '),
91+
};
92+
93+
if (handlerData.level === 'assert') {
94+
if (handlerData.args[0] === false) {
95+
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
96+
breadcrumb.data.arguments = handlerData.args.slice(1);
97+
} else {
98+
// Don't capture a breadcrumb for passed assertions
99+
return;
100+
}
101+
}
102+
103+
addBreadcrumb(breadcrumb, {
104+
input: handlerData.args,
105+
level: handlerData.level,
106+
});
107+
};
108+
}
109+
110+
/**
111+
* Creates breadcrumbs from fetch API calls
112+
*/
113+
function _getFetchBreadcrumbHandler(client: Client): (handlerData: HandlerDataFetch) => void {
114+
return function _fetchBreadcrumb(handlerData: HandlerDataFetch): void {
115+
if (getClient() !== client) {
116+
return;
117+
}
118+
119+
const { startTimestamp, endTimestamp } = handlerData;
120+
121+
// We only capture complete fetch requests
122+
if (!endTimestamp) {
123+
return;
124+
}
125+
126+
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
127+
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
128+
return;
129+
}
130+
131+
if (handlerData.error) {
132+
const data: FetchBreadcrumbData = handlerData.fetchData;
133+
const hint: FetchBreadcrumbHint = {
134+
data: handlerData.error,
135+
input: handlerData.args,
136+
startTimestamp,
137+
endTimestamp,
138+
};
139+
140+
addBreadcrumb(
141+
{
142+
category: 'fetch',
143+
data,
144+
level: 'error',
145+
type: 'http',
146+
},
147+
hint,
148+
);
149+
} else {
150+
const response = handlerData.response as Response | undefined;
151+
const data: FetchBreadcrumbData = {
152+
...handlerData.fetchData,
153+
status_code: response && response.status,
154+
};
155+
const hint: FetchBreadcrumbHint = {
156+
input: handlerData.args,
157+
response,
158+
startTimestamp,
159+
endTimestamp,
160+
};
161+
addBreadcrumb(
162+
{
163+
category: 'fetch',
164+
data,
165+
type: 'http',
166+
},
167+
hint,
168+
);
169+
}
170+
};
171+
}

packages/deno/src/sdk.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import { breadcrumbsIntegration, dedupeIntegration } from '@sentry/browser';
21
import type { ServerRuntimeClientOptions } from '@sentry/core';
3-
import { functionToStringIntegration, inboundFiltersIntegration, linkedErrorsIntegration } from '@sentry/core';
2+
import {
3+
dedupeIntegration,
4+
functionToStringIntegration,
5+
inboundFiltersIntegration,
6+
linkedErrorsIntegration,
7+
} from '@sentry/core';
48
import { getIntegrationsToSetup, initAndBind } from '@sentry/core';
59
import type { Integration, Options, StackParser } from '@sentry/types';
610
import { createStackParser, nodeStackLineParser, stackParserFromStackParserOptions } from '@sentry/utils';
711

812
import { DenoClient } from './client';
13+
import { breadcrumbsIntegration } from './integrations/breadcrumbs';
914
import { denoContextIntegration } from './integrations/context';
1015
import { contextLinesIntegration } from './integrations/contextlines';
1116
import { globalHandlersIntegration } from './integrations/globalhandlers';
@@ -21,14 +26,9 @@ export function getDefaultIntegrations(_options: Options): Integration[] {
2126
inboundFiltersIntegration(),
2227
functionToStringIntegration(),
2328
linkedErrorsIntegration(),
24-
// From Browser
2529
dedupeIntegration(),
26-
breadcrumbsIntegration({
27-
dom: false,
28-
history: false,
29-
xhr: false,
30-
}),
3130
// Deno Specific
31+
breadcrumbsIntegration(),
3232
denoContextIntegration(),
3333
contextLinesIntegration(),
3434
normalizePathsIntegration(),

0 commit comments

Comments
 (0)