@@ -552,6 +552,7 @@ private void ClearSession()
552552
553553 ActiveCall = null ;
554554 CallState = CallingState . Unknown ;
555+ _httpClient = null ;
555556
556557 _trackSubscriptionRequested = false ;
557558 _trackSubscriptionRequestInProgress = false ;
@@ -601,10 +602,11 @@ private void TryExecuteSubscribeToTracks()
601602 /// </summary>
602603 private async Task SubscribeToTracksAsync ( )
603604 {
604- if ( ActiveCall . Participants == null || ! ActiveCall . Participants . Any ( ) )
605+ if ( ActiveCall ? . Participants == null || ! ActiveCall . Participants . Any ( ) )
605606 {
606607#if STREAM_DEBUG_ENABLED
607- _logs . Error ( $ "{ nameof ( SubscribeToTracksAsync ) } Ignored - No participants in the call to subscribe tracks for") ;
608+ _logs . Error (
609+ $ "{ nameof ( SubscribeToTracksAsync ) } Ignored - No participants in the call to subscribe tracks for") ;
608610#endif
609611
610612 return ;
@@ -640,7 +642,7 @@ private async Task SubscribeToTracksAsync()
640642 return ;
641643 }
642644
643- if ( response . Error != null )
645+ if ( response ? . Error != null )
644646 {
645647 _logs . Error ( response . Error . Message ) ;
646648 }
@@ -655,6 +657,12 @@ private IEnumerable<TrackSubscriptionDetails> GetDesiredTracksDetails()
655657
656658 foreach ( var participant in ActiveCall . Participants )
657659 {
660+ if ( participant == null )
661+ {
662+ _logs . Error ( "Cannot subscribe to tracks - participant is null" ) ;
663+ continue ;
664+ }
665+
658666 if ( participant . IsLocalParticipant )
659667 {
660668 continue ;
@@ -668,9 +676,16 @@ private IEnumerable<TrackSubscriptionDetails> GetDesiredTracksDetails()
668676 //This was before changing the IUpdateableFrom<CallParticipantResponseInternalDTO, StreamVideoCallParticipant>.UpdateFromDto
669677 //to extract UserId from User obj
670678
679+ var userId = GetUserId ( participant ) ;
680+ if ( string . IsNullOrEmpty ( userId ) )
681+ {
682+ _logs . Error ( $ "Cannot subscribe to { trackType } - participant UserId is null or empty. SessionID: { participant . SessionId } ") ;
683+ continue ;
684+ }
685+
671686 yield return new TrackSubscriptionDetails
672687 {
673- UserId = GetUserId ( participant ) ,
688+ UserId = userId ,
674689 SessionId = participant . SessionId ,
675690 TrackType = trackType ,
676691 Dimension = requestedVideoResolution . ToVideoDimension ( )
@@ -1067,8 +1082,15 @@ private void OnSfuDominantSpeakerChanged(DominantSpeakerChanged dominantSpeakerC
10671082 private void OnSfuWebSocketOnError ( SfuError obj )
10681083 {
10691084 _sfuTracer ? . Trace ( PeerConnectionTraceKey . SfuError , obj ) ;
1085+ if ( CallState == CallingState . Offline )
1086+ {
1087+ return ;
1088+ }
1089+
10701090 _logs . Error (
10711091 $ "Sfu Error - Code: { obj . Error_ . Code } , Message: { obj . Error_ . Message } , ShouldRetry: { obj . Error_ . ShouldRetry } ") ;
1092+
1093+ //StreamTODO: add event here
10721094 }
10731095
10741096 private void OnSfuPinsUpdated ( PinsChanged pinsChanged )
@@ -1164,6 +1186,15 @@ private async Task<TResponse> RpcCallAsync<TRequest, TResponse>(TRequest request
11641186 {
11651187 //StreamTodo: use rpcCallAsync.GetMethodInfo().Name; instead debugRequestName
11661188
1189+ if ( _httpClient == null )
1190+ {
1191+ var errorMsg
1192+ = $ "[RPC Call: { debugRequestName } ] Failed - Attempted to execute RPC call but HttpClient is not yet initialized. " +
1193+ $ "CallState: { CallState } , ActiveCall: { ActiveCall != null } , SessionId: { SessionId ?? "null" } ";
1194+ _logs . Error ( errorMsg ) ;
1195+ throw new InvalidOperationException ( errorMsg ) ;
1196+ }
1197+
11671198 var skipTracing = debugRequestName == nameof ( GeneratedAPI . SendStats ) ;
11681199
11691200 // Trace the RPC request (except SendStats to avoid noise)
0 commit comments