1 | Object.defineProperty(exports, "__esModule", { value: true });
|
2 | var utils_1 = require("@sentry/utils");
|
3 | var fs_1 = require("fs");
|
4 | var lru_map_1 = require("lru_map");
|
5 | var stacktrace = require("./stacktrace");
|
6 |
|
7 | var DEFAULT_LINES_OF_CONTEXT = 7;
|
8 | var FILE_CONTENT_CACHE = new lru_map_1.LRUMap(100);
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | function resetFileContentCache() {
|
14 | FILE_CONTENT_CACHE.clear();
|
15 | }
|
16 | exports.resetFileContentCache = resetFileContentCache;
|
17 |
|
18 | function getFunction(frame) {
|
19 | try {
|
20 | return frame.functionName || frame.typeName + "." + (frame.methodName || '<anonymous>');
|
21 | }
|
22 | catch (e) {
|
23 |
|
24 |
|
25 |
|
26 | return '<anonymous>';
|
27 | }
|
28 | }
|
29 | var mainModule = ((require.main && require.main.filename && utils_1.dirname(require.main.filename)) ||
|
30 | global.process.cwd()) + "/";
|
31 |
|
32 | function getModule(filename, base) {
|
33 | if (!base) {
|
34 | base = mainModule;
|
35 | }
|
36 |
|
37 | var file = utils_1.basename(filename, '.js');
|
38 | filename = utils_1.dirname(filename);
|
39 | var n = filename.lastIndexOf('/node_modules/');
|
40 | if (n > -1) {
|
41 |
|
42 | return filename.substr(n + 14).replace(/\//g, '.') + ":" + file;
|
43 | }
|
44 |
|
45 |
|
46 | n = (filename + "/").lastIndexOf(base, 0);
|
47 | if (n === 0) {
|
48 | var moduleName = filename.substr(base.length).replace(/\//g, '.');
|
49 | if (moduleName) {
|
50 | moduleName += ':';
|
51 | }
|
52 | moduleName += file;
|
53 | return moduleName;
|
54 | }
|
55 | return file;
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | function readSourceFiles(filenames) {
|
64 |
|
65 | if (filenames.length === 0) {
|
66 | return utils_1.SyncPromise.resolve({});
|
67 | }
|
68 | return new utils_1.SyncPromise(function (resolve) {
|
69 | var sourceFiles = {};
|
70 | var count = 0;
|
71 | var _loop_1 = function (i) {
|
72 | var filename = filenames[i];
|
73 | var cache = FILE_CONTENT_CACHE.get(filename);
|
74 |
|
75 | if (cache !== undefined) {
|
76 |
|
77 |
|
78 | if (cache !== null) {
|
79 | sourceFiles[filename] = cache;
|
80 | }
|
81 | count++;
|
82 |
|
83 |
|
84 | if (count === filenames.length) {
|
85 | resolve(sourceFiles);
|
86 | }
|
87 | return "continue";
|
88 | }
|
89 | fs_1.readFile(filename, function (err, data) {
|
90 | var content = err ? null : data.toString();
|
91 | sourceFiles[filename] = content;
|
92 |
|
93 |
|
94 | FILE_CONTENT_CACHE.set(filename, content);
|
95 | count++;
|
96 | if (count === filenames.length) {
|
97 | resolve(sourceFiles);
|
98 | }
|
99 | });
|
100 | };
|
101 |
|
102 | for (var i = 0; i < filenames.length; i++) {
|
103 | _loop_1(i);
|
104 | }
|
105 | });
|
106 | }
|
107 |
|
108 |
|
109 |
|
110 | function extractStackFromError(error) {
|
111 | var stack = stacktrace.parse(error);
|
112 | if (!stack) {
|
113 | return [];
|
114 | }
|
115 | return stack;
|
116 | }
|
117 | exports.extractStackFromError = extractStackFromError;
|
118 |
|
119 |
|
120 |
|
121 | function parseStack(stack, options) {
|
122 | var filesToRead = [];
|
123 | var linesOfContext = options && options.frameContextLines !== undefined ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT;
|
124 | var frames = stack.map(function (frame) {
|
125 | var parsedFrame = {
|
126 | colno: frame.columnNumber,
|
127 | filename: frame.fileName || '',
|
128 | function: getFunction(frame),
|
129 | lineno: frame.lineNumber,
|
130 | };
|
131 | var isInternal = frame.native ||
|
132 | (parsedFrame.filename &&
|
133 | !parsedFrame.filename.startsWith('/') &&
|
134 | !parsedFrame.filename.startsWith('.') &&
|
135 | parsedFrame.filename.indexOf(':\\') !== 1);
|
136 | // in_app is all that's not an internal Node function or a module within node_modules
|
137 | // note that isNative appears to return true even for node core libraries
|
138 | // see https://github.com/getsentry/raven-node/issues/176
|
139 | parsedFrame.in_app =
|
140 | !isInternal && parsedFrame.filename !== undefined && parsedFrame.filename.indexOf('node_modules/') === -1;
|
141 | // Extract a module name based on the filename
|
142 | if (parsedFrame.filename) {
|
143 | parsedFrame.module = getModule(parsedFrame.filename);
|
144 | if (!isInternal && linesOfContext > 0) {
|
145 | filesToRead.push(parsedFrame.filename);
|
146 | }
|
147 | }
|
148 | return parsedFrame;
|
149 | });
|
150 |
|
151 | if (linesOfContext <= 0) {
|
152 | return utils_1.SyncPromise.resolve(frames);
|
153 | }
|
154 | try {
|
155 | return addPrePostContext(filesToRead, frames, linesOfContext);
|
156 | }
|
157 | catch (_) {
|
158 |
|
159 |
|
160 | return utils_1.SyncPromise.resolve(frames);
|
161 | }
|
162 | }
|
163 | exports.parseStack = parseStack;
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | function addPrePostContext(filesToRead, frames, linesOfContext) {
|
171 | return new utils_1.SyncPromise(function (resolve) {
|
172 | return readSourceFiles(filesToRead).then(function (sourceFiles) {
|
173 | var result = frames.map(function (frame) {
|
174 | if (frame.filename && sourceFiles[frame.filename]) {
|
175 | try {
|
176 | var lines = sourceFiles[frame.filename].split('\n');
|
177 | utils_1.addContextToFrame(lines, frame, linesOfContext);
|
178 | }
|
179 | catch (e) {
|
180 |
|
181 |
|
182 | }
|
183 | }
|
184 | return frame;
|
185 | });
|
186 | resolve(result);
|
187 | });
|
188 | });
|
189 | }
|
190 |
|
191 |
|
192 |
|
193 | function getExceptionFromError(error, options) {
|
194 | var name = error.name || error.constructor.name;
|
195 | var stack = extractStackFromError(error);
|
196 | return new utils_1.SyncPromise(function (resolve) {
|
197 | return parseStack(stack, options).then(function (frames) {
|
198 | var result = {
|
199 | stacktrace: {
|
200 | frames: prepareFramesForEvent(frames),
|
201 | },
|
202 | type: name,
|
203 | value: error.message,
|
204 | };
|
205 | resolve(result);
|
206 | });
|
207 | });
|
208 | }
|
209 | exports.getExceptionFromError = getExceptionFromError;
|
210 |
|
211 |
|
212 |
|
213 | function parseError(error, options) {
|
214 | return new utils_1.SyncPromise(function (resolve) {
|
215 | return getExceptionFromError(error, options).then(function (exception) {
|
216 | resolve({
|
217 | exception: {
|
218 | values: [exception],
|
219 | },
|
220 | });
|
221 | });
|
222 | });
|
223 | }
|
224 | exports.parseError = parseError;
|
225 |
|
226 |
|
227 |
|
228 | function prepareFramesForEvent(stack) {
|
229 | if (!stack || !stack.length) {
|
230 | return [];
|
231 | }
|
232 | var localStack = stack;
|
233 | var firstFrameFunction = localStack[0].function || '';
|
234 | if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) {
|
235 | localStack = localStack.slice(1);
|
236 | }
|
237 |
|
238 | return localStack.reverse();
|
239 | }
|
240 | exports.prepareFramesForEvent = prepareFramesForEvent;
|
241 |
|
\ | No newline at end of file |