@@ -1929,4 +1929,34 @@ describe("webviewMessageHandler - telemetrySetting", () => {
19291929 const calls = vi . mocked ( TelemetryService . instance . updateTelemetryState ) . mock . calls
19301930 expect ( calls . at ( - 1 ) ) . toEqual ( [ false ] )
19311931 } )
1932+
1933+ // CodeRabbit finding: webviewDidLaunch's queued telemetry update called
1934+ // TelemetryService.instance directly, unlike the "telemetrySetting" case a few lines
1935+ // below which checks hasInstance() first. If webviewDidLaunch fires before the service
1936+ // is created (e.g. during activation), TelemetryService.instance throws -- and since
1937+ // this whole chain isn't awaited by the "webviewDidLaunch" case, that throw becomes an
1938+ // unhandled promise rejection instead of a no-op.
1939+ it ( "does not throw or update telemetry state when webviewDidLaunch fires before TelemetryService exists" , async ( ) => {
1940+ const { TelemetryService } = await import ( "@roo-code/telemetry" )
1941+ vi . mocked ( TelemetryService . hasInstance ) . mockReturnValue ( false )
1942+
1943+ vi . mocked ( mockClineProvider . contextProxy . getValue ) . mockReturnValue ( "unset" )
1944+ vi . mocked ( mockClineProvider . customModesManager . getCustomModes ) . mockResolvedValue ( [ ] )
1945+ const providerForLaunch = mockClineProvider as unknown as {
1946+ getMcpHub : ReturnType < typeof vi . fn >
1947+ providerSettingsManager : { listConfig : ReturnType < typeof vi . fn > }
1948+ getStateToPostToWebview : ReturnType < typeof vi . fn >
1949+ }
1950+ providerForLaunch . getMcpHub = vi . fn ( ) . mockReturnValue ( undefined )
1951+ providerForLaunch . providerSettingsManager = { listConfig : vi . fn ( ) . mockResolvedValue ( undefined ) }
1952+ providerForLaunch . getStateToPostToWebview = vi . fn ( ) . mockResolvedValue ( { telemetrySetting : "unset" } )
1953+
1954+ await expect ( webviewMessageHandler ( mockClineProvider , { type : "webviewDidLaunch" } ) ) . resolves . not . toThrow ( )
1955+
1956+ // The queued telemetry update is fire-and-forget from the handler's own point of
1957+ // view -- flush a microtask turn so its .then() callback runs before asserting.
1958+ await Promise . resolve ( )
1959+
1960+ expect ( TelemetryService . instance . updateTelemetryState ) . not . toHaveBeenCalled ( )
1961+ } )
19321962} )
0 commit comments