11import { getCurrentHub } from '@sentry/core' ;
2- import { Event , EventProcessor , Integration } from '@sentry/types' ;
2+ import { Event , EventProcessor , Integration , StackFrame } from '@sentry/types' ;
33import { addContextToFrame } from '@sentry/utils' ;
44import { readFile } from 'fs' ;
55import { LRUMap } from 'lru_map' ;
@@ -73,23 +73,26 @@ export class ContextLines implements Integration {
7373
7474 /** Processes an event and adds context lines */
7575 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 ) ;
8480 }
8581 }
82+ }
83+
84+ return event ;
85+ }
8686
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 ) ;
8892
89- for ( const frame of frames ) {
90- if ( frame . filename && sourceFiles [ frame . filename ] ) {
93+ if ( sourceFile ) {
9194 try {
92- const lines = ( sourceFiles [ frame . filename ] as string ) . split ( '\n' ) ;
95+ const lines = sourceFile . split ( '\n' ) ;
9396 addContextToFrame ( lines , frame , contextLines ) ;
9497 } catch ( e ) {
9598 // anomaly, being defensive in case
@@ -98,43 +101,28 @@ export class ContextLines implements Integration {
98101 }
99102 }
100103 }
101-
102- return event ;
103104 }
104105}
105106
106107/**
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.
108109 *
109- * @param filenames Array of filepaths to read content from.
110+ * @param filename filepath to read content from.
110111 */
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+ }
134118
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+ //
137124 }
138125
139- return sourceFiles ;
126+ FILE_CONTENT_CACHE . set ( filename , content ) ;
127+ return content ;
140128}
0 commit comments