1515
1616using System ;
1717using System . Collections . Generic ;
18- using System . Linq ;
19- using MongoDB . Bson ;
18+ using MongoDB . Driver . Core . Misc ;
2019
2120namespace MongoDB . Driver . Core . Operations
2221{
2322 internal static class RetryabilityHelper
2423 {
2524 // private constants
25+ private const string ResumableChangeStreamErrorLabel = "ResumableChangeStreamError" ;
2626 private const string RetryableWriteErrorLabel = "RetryableWriteError" ;
2727
2828 // private static fields
29- private static readonly HashSet < ServerErrorCode > __notResumableChangeStreamErrorCodes ;
30- private static readonly HashSet < string > __notResumableChangeStreamErrorLabels ;
29+ private static readonly HashSet < ServerErrorCode > __resumableChangeStreamErrorCodes ;
3130 private static readonly HashSet < Type > __resumableChangeStreamExceptions ;
3231 private static readonly HashSet < Type > __retryableReadExceptions ;
3332 private static readonly HashSet < Type > __retryableWriteExceptions ;
@@ -39,15 +38,11 @@ static RetryabilityHelper()
3938 {
4039 var resumableAndRetryableExceptions = new HashSet < Type > ( )
4140 {
42- typeof ( MongoConnectionException ) ,
4341 typeof ( MongoNotPrimaryException ) ,
4442 typeof ( MongoNodeIsRecoveringException )
4543 } ;
4644
47- __resumableChangeStreamExceptions = new HashSet < Type > ( resumableAndRetryableExceptions )
48- {
49- typeof ( MongoCursorNotFoundException )
50- } ;
45+ __resumableChangeStreamExceptions = new HashSet < Type > ( resumableAndRetryableExceptions ) ;
5146
5247 __retryableReadExceptions = new HashSet < Type > ( resumableAndRetryableExceptions ) ;
5348
@@ -68,16 +63,25 @@ static RetryabilityHelper()
6863 ServerErrorCode . ExceededTimeLimit
6964 } ;
7065
71- __notResumableChangeStreamErrorCodes = new HashSet < ServerErrorCode > ( )
72- {
73- ServerErrorCode . CappedPositionLost ,
74- ServerErrorCode . CursorKilled ,
75- ServerErrorCode . Interrupted
76- } ;
77-
78- __notResumableChangeStreamErrorLabels = new HashSet < string > ( )
66+ __resumableChangeStreamErrorCodes = new HashSet < ServerErrorCode > ( )
7967 {
80- "NonResumableChangeStreamError"
68+ ServerErrorCode . HostUnreachable ,
69+ ServerErrorCode . HostNotFound ,
70+ ServerErrorCode . NetworkTimeout ,
71+ ServerErrorCode . ShutdownInProgress ,
72+ ServerErrorCode . PrimarySteppedDown ,
73+ ServerErrorCode . ExceededTimeLimit ,
74+ ServerErrorCode . SocketException ,
75+ ServerErrorCode . NotMaster ,
76+ ServerErrorCode . InterruptedAtShutdown ,
77+ ServerErrorCode . InterruptedDueToReplStateChange ,
78+ ServerErrorCode . NotMasterNoSlaveOk ,
79+ ServerErrorCode . NotMasterOrSecondary ,
80+ ServerErrorCode . StaleShardVersion ,
81+ ServerErrorCode . StaleEpoch ,
82+ ServerErrorCode . StaleConfig ,
83+ ServerErrorCode . RetryChangeStream ,
84+ ServerErrorCode . FailedToSatisfyReadPreference
8185 } ;
8286 }
8387
@@ -90,26 +94,41 @@ public static void AddRetryableWriteErrorLabelIfRequired(MongoException exceptio
9094 }
9195 }
9296
93- public static bool IsResumableChangeStreamException ( Exception exception )
97+ public static bool IsNetworkException ( Exception exception )
9498 {
95- var commandException = exception as MongoCommandException ;
96- if ( commandException != null )
99+ return exception is MongoConnectionException mongoConnectionException && mongoConnectionException . IsNetworkException ;
100+ }
101+
102+ public static bool IsResumableChangeStreamException ( Exception exception , SemanticVersion serverVersion )
103+ {
104+ if ( IsNetworkException ( exception ) )
97105 {
98- var code = ( ServerErrorCode ) commandException . Code ;
99- var isNonResumable =
100- __notResumableChangeStreamErrorCodes . Contains ( code ) ||
101- __notResumableChangeStreamErrorLabels . Any ( c => commandException . HasErrorLabel ( c ) ) ;
102- return ! isNonResumable ;
106+ return true ;
107+ }
108+
109+ if ( Feature . ServerReturnsResumableChangeStreamErrorLabel . IsSupported ( serverVersion ) )
110+ {
111+ return exception is MongoException mongoException ? mongoException . HasErrorLabel ( ResumableChangeStreamErrorLabel ) : false ;
103112 }
104113 else
105114 {
115+ var commandException = exception as MongoCommandException ;
116+ if ( commandException != null )
117+ {
118+ var code = ( ServerErrorCode ) commandException . Code ;
119+ if ( __resumableChangeStreamErrorCodes . Contains ( code ) )
120+ {
121+ return true ;
122+ }
123+ }
124+
106125 return __resumableChangeStreamExceptions . Contains ( exception . GetType ( ) ) ;
107126 }
108127 }
109128
110129 public static bool IsRetryableReadException ( Exception exception )
111130 {
112- if ( __retryableReadExceptions . Contains ( exception . GetType ( ) ) )
131+ if ( __retryableReadExceptions . Contains ( exception . GetType ( ) ) || IsNetworkException ( exception ) )
113132 {
114133 return true ;
115134 }
@@ -135,7 +154,7 @@ public static bool IsRetryableWriteException(Exception exception)
135154 // private static methods
136155 private static bool ShouldRetryableWriteExceptionLabelBeAdded ( Exception exception )
137156 {
138- if ( __retryableWriteExceptions . Contains ( exception . GetType ( ) ) )
157+ if ( __retryableWriteExceptions . Contains ( exception . GetType ( ) ) || IsNetworkException ( exception ) )
139158 {
140159 return true ;
141160 }
0 commit comments