Skip to content

Commit 2e5d850

Browse files
authored
chore(browser): Add attribution and licences for stack parsers (#7620)
1 parent 02d065d commit 2e5d850

File tree

3 files changed

+143
-90
lines changed

3 files changed

+143
-90
lines changed

packages/browser/src/stack-parsers.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
// This was originally forked from https://github.com/csnover/TraceKit, and was largely
2+
// re - written as part of raven - js.
3+
//
4+
// This code was later copied to the JavaScript mono - repo and further modified and
5+
// refactored over the years.
6+
7+
// Copyright (c) 2013 Onur Can Cakmak [email protected] and all TraceKit contributors.
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
10+
// software and associated documentation files(the 'Software'), to deal in the Software
11+
// without restriction, including without limitation the rights to use, copy, modify,
12+
// merge, publish, distribute, sublicense, and / or sell copies of the Software, and to
13+
// permit persons to whom the Software is furnished to do so, subject to the following
14+
// conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in all copies
17+
// or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
20+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
21+
// PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23+
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
24+
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
126
import type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/types';
227
import { createStackParser } from '@sentry/utils';
328

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// This code was originally forked from https://github.com/felixge/node-stack-trace
2+
// Since then it has been highly modified to fit our needs.
3+
4+
// Copyright (c) 2011 Felix Geisendörfer ([email protected])//
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions://
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.//
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
24+
import type { StackLineParserFn } from '@sentry/types';
25+
26+
export type GetModuleFn = (filename: string | undefined) => string | undefined;
27+
28+
/** Node Stack line parser */
29+
// eslint-disable-next-line complexity
30+
export function node(getModule?: GetModuleFn): StackLineParserFn {
31+
const FILENAME_MATCH = /^\s*[-]{4,}$/;
32+
const FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
33+
34+
// eslint-disable-next-line complexity
35+
return (line: string) => {
36+
const lineMatch = line.match(FULL_MATCH);
37+
38+
if (lineMatch) {
39+
let object: string | undefined;
40+
let method: string | undefined;
41+
let functionName: string | undefined;
42+
let typeName: string | undefined;
43+
let methodName: string | undefined;
44+
45+
if (lineMatch[1]) {
46+
functionName = lineMatch[1];
47+
48+
let methodStart = functionName.lastIndexOf('.');
49+
if (functionName[methodStart - 1] === '.') {
50+
methodStart--;
51+
}
52+
53+
if (methodStart > 0) {
54+
object = functionName.slice(0, methodStart);
55+
method = functionName.slice(methodStart + 1);
56+
const objectEnd = object.indexOf('.Module');
57+
if (objectEnd > 0) {
58+
functionName = functionName.slice(objectEnd + 1);
59+
object = object.slice(0, objectEnd);
60+
}
61+
}
62+
typeName = undefined;
63+
}
64+
65+
if (method) {
66+
typeName = object;
67+
methodName = method;
68+
}
69+
70+
if (method === '<anonymous>') {
71+
methodName = undefined;
72+
functionName = undefined;
73+
}
74+
75+
if (functionName === undefined) {
76+
methodName = methodName || '<anonymous>';
77+
functionName = typeName ? `${typeName}.${methodName}` : methodName;
78+
}
79+
80+
let filename = lineMatch[2] && lineMatch[2].startsWith('file://') ? lineMatch[2].slice(7) : lineMatch[2];
81+
const isNative = lineMatch[5] === 'native';
82+
83+
if (!filename && lineMatch[5] && !isNative) {
84+
filename = lineMatch[5];
85+
}
86+
87+
const isInternal =
88+
isNative || (filename && !filename.startsWith('/') && !filename.startsWith('.') && !filename.includes(':\\'));
89+
90+
// in_app is all that's not an internal Node function or a module within node_modules
91+
// note that isNative appears to return true even for node core libraries
92+
// see https://github.com/getsentry/raven-node/issues/176
93+
94+
const in_app = !isInternal && filename !== undefined && !filename.includes('node_modules/');
95+
96+
return {
97+
filename,
98+
module: getModule ? getModule(filename) : undefined,
99+
function: functionName,
100+
lineno: parseInt(lineMatch[3], 10) || undefined,
101+
colno: parseInt(lineMatch[4], 10) || undefined,
102+
in_app,
103+
};
104+
}
105+
106+
if (line.match(FILENAME_MATCH)) {
107+
return {
108+
filename: line,
109+
};
110+
}
111+
112+
return undefined;
113+
};
114+
}

packages/utils/src/stacktrace.ts

Lines changed: 4 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import type { StackFrame, StackLineParser, StackLineParserFn, StackParser } from '@sentry/types';
1+
import type { StackFrame, StackLineParser, StackParser } from '@sentry/types';
2+
3+
import type { GetModuleFn } from './node-stack-trace';
4+
import { node } from './node-stack-trace';
25

36
const STACKTRACE_FRAME_LIMIT = 50;
47
// Used to sanitize webpack (error: *) wrapped stack errors
@@ -116,95 +119,6 @@ export function getFunctionName(fn: unknown): string {
116119
}
117120
}
118121

119-
type GetModuleFn = (filename: string | undefined) => string | undefined;
120-
121-
// eslint-disable-next-line complexity
122-
function node(getModule?: GetModuleFn): StackLineParserFn {
123-
const FILENAME_MATCH = /^\s*[-]{4,}$/;
124-
const FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
125-
126-
// eslint-disable-next-line complexity
127-
return (line: string) => {
128-
const lineMatch = line.match(FULL_MATCH);
129-
130-
if (lineMatch) {
131-
let object: string | undefined;
132-
let method: string | undefined;
133-
let functionName: string | undefined;
134-
let typeName: string | undefined;
135-
let methodName: string | undefined;
136-
137-
if (lineMatch[1]) {
138-
functionName = lineMatch[1];
139-
140-
let methodStart = functionName.lastIndexOf('.');
141-
if (functionName[methodStart - 1] === '.') {
142-
methodStart--;
143-
}
144-
145-
if (methodStart > 0) {
146-
object = functionName.slice(0, methodStart);
147-
method = functionName.slice(methodStart + 1);
148-
const objectEnd = object.indexOf('.Module');
149-
if (objectEnd > 0) {
150-
functionName = functionName.slice(objectEnd + 1);
151-
object = object.slice(0, objectEnd);
152-
}
153-
}
154-
typeName = undefined;
155-
}
156-
157-
if (method) {
158-
typeName = object;
159-
methodName = method;
160-
}
161-
162-
if (method === '<anonymous>') {
163-
methodName = undefined;
164-
functionName = undefined;
165-
}
166-
167-
if (functionName === undefined) {
168-
methodName = methodName || '<anonymous>';
169-
functionName = typeName ? `${typeName}.${methodName}` : methodName;
170-
}
171-
172-
let filename = lineMatch[2] && lineMatch[2].startsWith('file://') ? lineMatch[2].slice(7) : lineMatch[2];
173-
const isNative = lineMatch[5] === 'native';
174-
175-
if (!filename && lineMatch[5] && !isNative) {
176-
filename = lineMatch[5];
177-
}
178-
179-
const isInternal =
180-
isNative || (filename && !filename.startsWith('/') && !filename.startsWith('.') && !filename.includes(':\\'));
181-
182-
// in_app is all that's not an internal Node function or a module within node_modules
183-
// note that isNative appears to return true even for node core libraries
184-
// see https://github.com/getsentry/raven-node/issues/176
185-
186-
const in_app = !isInternal && filename !== undefined && !filename.includes('node_modules/');
187-
188-
return {
189-
filename,
190-
module: getModule ? getModule(filename) : undefined,
191-
function: functionName,
192-
lineno: parseInt(lineMatch[3], 10) || undefined,
193-
colno: parseInt(lineMatch[4], 10) || undefined,
194-
in_app,
195-
};
196-
}
197-
198-
if (line.match(FILENAME_MATCH)) {
199-
return {
200-
filename: line,
201-
};
202-
}
203-
204-
return undefined;
205-
};
206-
}
207-
208122
/**
209123
* Node.js stack line parser
210124
*

0 commit comments

Comments
 (0)