1
1
import { getCurrentHub } from '@sentry/core' ;
2
- import { Event , EventProcessor , Integration } from '@sentry/types' ;
2
+ import { Event , EventProcessor , Integration , StackFrame } from '@sentry/types' ;
3
3
import { addContextToFrame } from '@sentry/utils' ;
4
4
import { readFile } from 'fs' ;
5
5
import { LRUMap } from 'lru_map' ;
@@ -73,23 +73,26 @@ export class ContextLines implements Integration {
73
73
74
74
/** Processes an event and adds context lines */
75
75
public async addSourceContext ( event : Event , contextLines : number ) : Promise < Event > {
76
- const frames = event . exception ?. values ?. [ 0 ] . stacktrace ?. frames ;
77
-
78
- if ( frames && contextLines > 0 ) {
79
- const filenames : Set < string > = new Set ( ) ;
80
-
81
- for ( const frame of frames ) {
82
- if ( frame . filename ) {
83
- filenames . add ( frame . filename ) ;
76
+ if ( contextLines > 0 && event . exception ?. values ) {
77
+ for ( const exception of event . exception . values ) {
78
+ if ( exception . stacktrace ?. frames ) {
79
+ await this . _addSourceContextToFrames ( exception . stacktrace . frames , contextLines ) ;
84
80
}
85
81
}
82
+ }
83
+
84
+ return event ;
85
+ }
86
86
87
- const sourceFiles = await readSourceFiles ( filenames ) ;
87
+ /** Adds context lines to frames */
88
+ public async _addSourceContextToFrames ( frames : StackFrame [ ] , contextLines : number ) : Promise < void > {
89
+ for ( const frame of frames ) {
90
+ if ( frame . filename ) {
91
+ const sourceFile = await _readSourceFile ( frame . filename ) ;
88
92
89
- for ( const frame of frames ) {
90
- if ( frame . filename && sourceFiles [ frame . filename ] ) {
93
+ if ( sourceFile ) {
91
94
try {
92
- const lines = ( sourceFiles [ frame . filename ] as string ) . split ( '\n' ) ;
95
+ const lines = sourceFile . split ( '\n' ) ;
93
96
addContextToFrame ( lines , frame , contextLines ) ;
94
97
} catch ( e ) {
95
98
// anomaly, being defensive in case
@@ -98,43 +101,28 @@ export class ContextLines implements Integration {
98
101
}
99
102
}
100
103
}
101
-
102
- return event ;
103
104
}
104
105
}
105
106
106
107
/**
107
- * This function reads file contents and caches them in a global LRU cache.
108
+ * Reads file contents and caches them in a global LRU cache.
108
109
*
109
- * @param filenames Array of filepaths to read content from.
110
+ * @param filename filepath to read content from.
110
111
*/
111
- async function readSourceFiles ( filenames : Set < string > ) : Promise < Record < string , string | null > > {
112
- const sourceFiles : Record < string , string | null > = { } ;
113
-
114
- for ( const filename of filenames ) {
115
- const cachedFile = FILE_CONTENT_CACHE . get ( filename ) ;
116
- // We have a cache hit
117
- if ( cachedFile !== undefined ) {
118
- // If stored value is null, it means that we already tried, but couldn't read the content of the file. Skip.
119
- if ( cachedFile === null ) {
120
- continue ;
121
- }
122
-
123
- // Otherwise content is there, so reuse cached value.
124
- sourceFiles [ filename ] = cachedFile ;
125
- continue ;
126
- }
127
-
128
- let content : string | null = null ;
129
- try {
130
- content = await readTextFileAsync ( filename ) ;
131
- } catch ( _ ) {
132
- //
133
- }
112
+ async function _readSourceFile ( filename : string ) : Promise < string | null > {
113
+ const cachedFile = FILE_CONTENT_CACHE . get ( filename ) ;
114
+ // We have a cache hit
115
+ if ( cachedFile !== undefined ) {
116
+ return cachedFile ;
117
+ }
134
118
135
- FILE_CONTENT_CACHE . set ( filename , content ) ;
136
- sourceFiles [ filename ] = content ;
119
+ let content : string | null = null ;
120
+ try {
121
+ content = await readTextFileAsync ( filename ) ;
122
+ } catch ( _ ) {
123
+ //
137
124
}
138
125
139
- return sourceFiles ;
126
+ FILE_CONTENT_CACHE . set ( filename , content ) ;
127
+ return content ;
140
128
}
0 commit comments