Skip to content

Commit 407543d

Browse files
committed
feat(node-experimental): Move defaultStackParser & getSentryRelease
These were imported from `@sentry/node` before. Also moves the `createGetModuleFromFilename` utility over, which is needed for `defaultStackParser`.
1 parent 4f92ff0 commit 407543d

File tree

4 files changed

+102
-7
lines changed

4 files changed

+102
-7
lines changed

packages/node-experimental/src/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,21 @@ export * as Handlers from './sdk/handlers';
1717
export type { Span } from './types';
1818

1919
export { startSpan, startSpanManual, startInactiveSpan, getActiveSpan, withActiveSpan } from '@sentry/opentelemetry';
20-
export { getClient } from './sdk/api';
20+
export { getClient, getSentryRelease, defaultStackParser } from './sdk/api';
21+
export { createGetModuleFromFilename } from './utils/module';
2122
// eslint-disable-next-line deprecation/deprecation
2223
export { getCurrentHub } from './sdk/hub';
2324

2425
export {
2526
addBreadcrumb,
2627
isInitialized,
2728
makeNodeTransport,
28-
defaultStackParser,
29-
getSentryRelease,
3029
getGlobalScope,
3130
addRequestDataToEvent,
3231
DEFAULT_USER_INCLUDES,
3332
extractRequestData,
3433
// eslint-disable-next-line deprecation/deprecation
3534
getModuleFromFilename,
36-
createGetModuleFromFilename,
3735
close,
3836
createTransport,
3937
flush,

packages/node-experimental/src/sdk/api.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// PUBLIC APIS
22

33
import { getCurrentScope } from '@sentry/core';
4-
import type { Client } from '@sentry/types';
4+
import type { Client, StackParser } from '@sentry/types';
5+
import { GLOBAL_OBJ, createStackParser, nodeStackLineParser } from '@sentry/utils';
6+
import { createGetModuleFromFilename } from '../utils/module';
57

68
/** Get the currently active client. */
79
export function getClient<C extends Client>(): C {
@@ -15,3 +17,40 @@ export function getClient<C extends Client>(): C {
1517
// TODO otherwise ensure we use a noop client
1618
return {} as C;
1719
}
20+
21+
/**
22+
* Returns a release dynamically from environment variables.
23+
*/
24+
export function getSentryRelease(fallback?: string): string | undefined {
25+
// Always read first as Sentry takes this as precedence
26+
if (process.env.SENTRY_RELEASE) {
27+
return process.env.SENTRY_RELEASE;
28+
}
29+
30+
// This supports the variable that sentry-webpack-plugin injects
31+
if (GLOBAL_OBJ.SENTRY_RELEASE && GLOBAL_OBJ.SENTRY_RELEASE.id) {
32+
return GLOBAL_OBJ.SENTRY_RELEASE.id;
33+
}
34+
35+
return (
36+
// GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
37+
process.env.GITHUB_SHA ||
38+
// Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata
39+
process.env.COMMIT_REF ||
40+
// Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables
41+
process.env.VERCEL_GIT_COMMIT_SHA ||
42+
process.env.VERCEL_GITHUB_COMMIT_SHA ||
43+
process.env.VERCEL_GITLAB_COMMIT_SHA ||
44+
process.env.VERCEL_BITBUCKET_COMMIT_SHA ||
45+
// Zeit (now known as Vercel)
46+
process.env.ZEIT_GITHUB_COMMIT_SHA ||
47+
process.env.ZEIT_GITLAB_COMMIT_SHA ||
48+
process.env.ZEIT_BITBUCKET_COMMIT_SHA ||
49+
// Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables
50+
process.env.CF_PAGES_COMMIT_SHA ||
51+
fallback
52+
);
53+
}
54+
55+
/** Node.js stack parser */
56+
export const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(createGetModuleFromFilename()));

packages/node-experimental/src/sdk/init.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
startSession,
88
} from '@sentry/core';
99
import {
10-
defaultStackParser,
1110
getDefaultIntegrations as getDefaultNodeIntegrations,
1211
getSentryRelease,
12+
makeNodeTransport,
1313
spotlightIntegration,
1414
} from '@sentry/node';
1515
import { setOpenTelemetryContextAsyncContextStrategy } from '@sentry/opentelemetry';
@@ -26,9 +26,10 @@ import { DEBUG_BUILD } from '../debug-build';
2626
import { getAutoPerformanceIntegrations } from '../integrations/getAutoPerformanceIntegrations';
2727
import { httpIntegration } from '../integrations/http';
2828
import { nativeNodeFetchIntegration } from '../integrations/node-fetch';
29-
import { makeNodeTransport } from '../transports';
29+
import type { NodeExperimentalClientOptions, NodeExperimentalOptions } from '../types';
3030
import type { NodeClientOptions, NodeOptions } from '../types';
3131
import { NodeClient } from './client';
32+
import { defaultStackParser, getSentryRelease } from './api';
3233
import { initOtel } from './initOtel';
3334

3435
const ignoredDefaultIntegrations = ['Http', 'Undici'];
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { posix, sep } from 'path';
2+
import { dirname } from '@sentry/utils';
3+
4+
/** normalizes Windows paths */
5+
function normalizeWindowsPath(path: string): string {
6+
return path
7+
.replace(/^[A-Z]:/, '') // remove Windows-style prefix
8+
.replace(/\\/g, '/'); // replace all `\` instances with `/`
9+
}
10+
11+
/** Creates a function that gets the module name from a filename */
12+
export function createGetModuleFromFilename(
13+
basePath: string = process.argv[1] ? dirname(process.argv[1]) : process.cwd(),
14+
isWindows: boolean = sep === '\\',
15+
): (filename: string | undefined) => string | undefined {
16+
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
17+
18+
return (filename: string | undefined) => {
19+
if (!filename) {
20+
return;
21+
}
22+
23+
const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename;
24+
25+
// eslint-disable-next-line prefer-const
26+
let { dir, base: file, ext } = posix.parse(normalizedFilename);
27+
28+
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
29+
file = file.slice(0, ext.length * -1);
30+
}
31+
32+
if (!dir) {
33+
// No dirname whatsoever
34+
dir = '.';
35+
}
36+
37+
const n = dir.lastIndexOf('/node_modules');
38+
if (n > -1) {
39+
return `${dir.slice(n + 14).replace(/\//g, '.')}:${file}`;
40+
}
41+
42+
// Let's see if it's a part of the main module
43+
// To be a part of main module, it has to share the same base
44+
if (dir.startsWith(normalizedBase)) {
45+
let moduleName = dir.slice(normalizedBase.length + 1).replace(/\//g, '.');
46+
47+
if (moduleName) {
48+
moduleName += ':';
49+
}
50+
moduleName += file;
51+
52+
return moduleName;
53+
}
54+
55+
return file;
56+
};
57+
}

0 commit comments

Comments
 (0)