@@ -33,6 +33,13 @@ jest.mock('./container', () => ({
3333 } ,
3434} ) ) ;
3535
36+ // Mock SentryService
37+ jest . mock ( './sentry' , ( ) => ( {
38+ SentryService : {
39+ getInstance : jest . fn ( ) ,
40+ } ,
41+ } ) ) ;
42+
3643const mockContainerIsDebugging = ( ) => {
3744 ( Container . isDebugging as any ) = true ;
3845} ;
@@ -50,6 +57,13 @@ describe('Logger', () => {
5057 // Reset mocks
5158 jest . clearAllMocks ( ) ;
5259
60+ // Setup default SentryService mock to avoid crashes in other tests
61+ const { SentryService } = require ( './sentry' ) ;
62+ ( SentryService . getInstance as jest . Mock ) . mockReturnValue ( {
63+ isInitialized : jest . fn ( ) . mockReturnValue ( false ) ,
64+ captureException : jest . fn ( ) ,
65+ } ) ;
66+
5367 mockOutputChannel = expansionCastTo < LogOutputChannel > ( {
5468 dispose : jest . fn ( ) ,
5569 append : jest . fn ( ) ,
@@ -323,4 +337,100 @@ describe('Logger', () => {
323337 }
324338 } ) ;
325339 } ) ;
340+
341+ describe ( 'Sentry integration' , ( ) => {
342+ let mockSentryService : any ;
343+
344+ beforeEach ( ( ) => {
345+ // Set up Logger with Error level
346+ ( configuration . initializing as jest . Mock ) . mockReturnValue ( true ) ;
347+ ( configuration . get as jest . Mock ) . mockReturnValue ( OutputLevel . Errors ) ;
348+ Logger . configure ( expansionCastTo < ExtensionContext > ( { subscriptions : [ ] } ) ) ;
349+
350+ // Setup the mocked Sentry service to be returned by getInstance
351+ mockSentryService = {
352+ isInitialized : jest . fn ( ) ,
353+ captureException : jest . fn ( ) ,
354+ } ;
355+ const { SentryService } = require ( './sentry' ) ;
356+ ( SentryService . getInstance as jest . Mock ) . mockReturnValue ( mockSentryService ) ;
357+ mockSentryService . isInitialized . mockReturnValue ( true ) ;
358+ } ) ;
359+
360+ it ( 'should not capture exception to Sentry when not initialized' , ( ) => {
361+ mockSentryService . isInitialized . mockReturnValue ( false ) ;
362+
363+ const testError = new Error ( 'test error' ) ;
364+ Logger . error ( testError , 'Error message' ) ;
365+
366+ expect ( mockSentryService . captureException ) . not . toHaveBeenCalled ( ) ;
367+ } ) ;
368+
369+ it ( 'should include capturedBy in Sentry tags' , ( ) => {
370+ mockSentryService . isInitialized . mockReturnValue ( true ) ;
371+
372+ const testError = new Error ( 'test error' ) ;
373+ Logger . error ( testError , 'Error message' ) ;
374+
375+ expect ( mockSentryService . captureException ) . toHaveBeenCalledWith (
376+ testError ,
377+ expect . objectContaining ( {
378+ tags : expect . objectContaining ( {
379+ capturedBy : expect . any ( String ) ,
380+ } ) ,
381+ } ) ,
382+ ) ;
383+ } ) ;
384+
385+ it ( 'should include params in Sentry extra context' , ( ) => {
386+ mockSentryService . isInitialized . mockReturnValue ( true ) ;
387+
388+ const testError = new Error ( 'test error' ) ;
389+ Logger . error ( testError , 'Error message' , 'param1' , 'param2' ) ;
390+
391+ expect ( mockSentryService . captureException ) . toHaveBeenCalledWith (
392+ testError ,
393+ expect . objectContaining ( {
394+ extra : expect . objectContaining ( {
395+ params : [ 'param1' , 'param2' ] ,
396+ } ) ,
397+ } ) ,
398+ ) ;
399+ } ) ;
400+
401+ it ( 'should handle Sentry errors gracefully and continue logging' , ( ) => {
402+ mockSentryService . isInitialized . mockReturnValue ( true ) ;
403+ mockSentryService . captureException . mockImplementation ( ( ) => {
404+ throw new Error ( 'Sentry failed' ) ;
405+ } ) ;
406+
407+ const testError = new Error ( 'test error' ) ;
408+
409+ // Should not throw
410+ expect ( ( ) => {
411+ Logger . error ( testError , 'Error message' ) ;
412+ } ) . not . toThrow ( ) ;
413+
414+ // Should still log to output channel
415+ expect ( mockOutputChannel . appendLine ) . toHaveBeenCalled ( ) ;
416+ } ) ;
417+
418+ it ( 'should call Sentry before logging to output channel' , ( ) => {
419+ mockSentryService . isInitialized . mockReturnValue ( true ) ;
420+ const callOrder : string [ ] = [ ] ;
421+
422+ mockSentryService . captureException . mockImplementation ( ( ) => {
423+ callOrder . push ( 'sentry' ) ;
424+ } ) ;
425+
426+ ( mockOutputChannel . appendLine as jest . Mock ) . mockImplementation ( ( ) => {
427+ callOrder . push ( 'output' ) ;
428+ } ) ;
429+
430+ const testError = new Error ( 'test error' ) ;
431+ Logger . error ( testError , 'Error message' ) ;
432+
433+ expect ( callOrder ) . toEqual ( [ 'sentry' , 'output' ] ) ;
434+ } ) ;
435+ } ) ;
326436} ) ;
0 commit comments