18
18
package org .apache .cassandra .exceptions ;
19
19
20
20
import java .io .IOException ;
21
+ import java .util .HashMap ;
22
+ import java .util .Map ;
21
23
22
24
import com .google .common .primitives .Ints ;
23
25
24
26
import org .apache .cassandra .db .filter .TombstoneOverwhelmingException ;
27
+ import org .apache .cassandra .index .IndexBuildInProgressException ;
28
+ import org .apache .cassandra .index .IndexNotAvailableException ;
25
29
import org .apache .cassandra .index .sai .utils .AbortedOperationException ;
26
30
import org .apache .cassandra .io .IVersionedSerializer ;
27
31
import org .apache .cassandra .io .util .DataInputPlus ;
28
32
import org .apache .cassandra .io .util .DataOutputPlus ;
29
33
import org .apache .cassandra .utils .vint .VIntCoding ;
30
34
31
- import static java .lang .Math .max ;
32
35
import static org .apache .cassandra .net .MessagingService .VERSION_40 ;
33
36
34
37
public enum RequestFailureReason
@@ -37,10 +40,13 @@ public enum RequestFailureReason
37
40
READ_TOO_MANY_TOMBSTONES (1 ),
38
41
TIMEOUT (2 ),
39
42
INCOMPATIBLE_SCHEMA (3 ),
40
- INDEX_NOT_AVAILABLE (4 ),
41
- UNKNOWN_COLUMN (5 ),
42
- UNKNOWN_TABLE (6 ),
43
- REMOTE_STORAGE_FAILURE (7 );
43
+ INDEX_NOT_AVAILABLE (6 ), // We match it to Apache Cassandra's INDEX_NOT_AVAILABLE code introduced in 5.0
44
+ // The following codes are not present in Apache Cassandra's RequestFailureReason
45
+ // We should add new codes in HCD (which do not exist in Apache Cassandra) only with big numbers, to avoid conflicts
46
+ UNKNOWN_COLUMN (500 ),
47
+ UNKNOWN_TABLE (501 ),
48
+ REMOTE_STORAGE_FAILURE (502 ),
49
+ INDEX_BUILD_IN_PROGRESS (503 );
44
50
45
51
public static final Serializer serializer = new Serializer ();
46
52
@@ -58,26 +64,29 @@ public int codeForNativeProtocol()
58
64
return code ;
59
65
}
60
66
61
- private static final RequestFailureReason [] codeToReasonMap ;
67
+ private static final Map <Integer , RequestFailureReason > codeToReasonMap = new HashMap <>();
68
+ private static final Map <Class <? extends Throwable >, RequestFailureReason > exceptionToReasonMap = new HashMap <>();
62
69
63
70
static
64
71
{
65
72
RequestFailureReason [] reasons = values ();
66
73
67
- int max = -1 ;
68
- for (RequestFailureReason r : reasons )
69
- max = max (r .code , max );
70
-
71
- RequestFailureReason [] codeMap = new RequestFailureReason [max + 1 ];
72
-
73
74
for (RequestFailureReason reason : reasons )
74
75
{
75
- if (codeMap [ reason .code ] != null )
76
+ if (codeToReasonMap . put ( reason .code , reason ) != null )
76
77
throw new RuntimeException ("Two RequestFailureReason-s that map to the same code: " + reason .code );
77
- codeMap [reason .code ] = reason ;
78
78
}
79
79
80
- codeToReasonMap = codeMap ;
80
+ exceptionToReasonMap .put (TombstoneOverwhelmingException .class , READ_TOO_MANY_TOMBSTONES );
81
+ exceptionToReasonMap .put (IncompatibleSchemaException .class , INCOMPATIBLE_SCHEMA );
82
+ exceptionToReasonMap .put (AbortedOperationException .class , TIMEOUT );
83
+ exceptionToReasonMap .put (IndexNotAvailableException .class , INDEX_NOT_AVAILABLE );
84
+ exceptionToReasonMap .put (UnknownColumnException .class , UNKNOWN_COLUMN );
85
+ exceptionToReasonMap .put (UnknownTableException .class , UNKNOWN_TABLE );
86
+ exceptionToReasonMap .put (IndexBuildInProgressException .class , INDEX_BUILD_IN_PROGRESS );
87
+
88
+ if (exceptionToReasonMap .size () != reasons .length -2 )
89
+ throw new RuntimeException ("A new RequestFailureReasons was probably added and you may need to update the exceptionToReasonMap" );
81
90
}
82
91
83
92
public static RequestFailureReason fromCode (int code )
@@ -86,19 +95,18 @@ public static RequestFailureReason fromCode(int code)
86
95
throw new IllegalArgumentException ("RequestFailureReason code must be non-negative (got " + code + ')' );
87
96
88
97
// be forgiving and return UNKNOWN if we aren't aware of the code - for forward compatibility
89
- return code < codeToReasonMap .length ? codeToReasonMap [ code ] : UNKNOWN ;
98
+ return codeToReasonMap .getOrDefault ( code , UNKNOWN ) ;
90
99
}
91
100
92
101
public static RequestFailureReason forException (Throwable t )
93
102
{
94
- if (t instanceof TombstoneOverwhelmingException )
95
- return READ_TOO_MANY_TOMBSTONES ;
96
-
97
- if (t instanceof IncompatibleSchemaException )
98
- return INCOMPATIBLE_SCHEMA ;
103
+ RequestFailureReason r = exceptionToReasonMap .get (t .getClass ());
104
+ if (r != null )
105
+ return r ;
99
106
100
- if (t instanceof AbortedOperationException )
101
- return TIMEOUT ;
107
+ for (Map .Entry <Class <? extends Throwable >, RequestFailureReason > entry : exceptionToReasonMap .entrySet ())
108
+ if (entry .getKey ().isInstance (t ))
109
+ return entry .getValue ();
102
110
103
111
return UNKNOWN ;
104
112
}
0 commit comments