github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/retry/errors_data_test.go (about) 1 package retry 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 8 "google.golang.org/grpc" 9 grpcCodes "google.golang.org/grpc/codes" 10 grpcStatus "google.golang.org/grpc/status" 11 12 "github.com/ydb-platform/ydb-go-sdk/v3/internal/backoff" 13 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 14 ) 15 16 type idempotency bool 17 18 func (t idempotency) String() string { 19 if t { 20 return "idempotent" 21 } 22 23 return "non-idempotent" 24 } 25 26 const ( 27 idempotent = true 28 nonIdempotent = false 29 ) 30 31 var errsToCheck = []struct { 32 err error // given error 33 backoff backoff.Type // no backoff (=== no operationStatus), fast backoff, slow backoff 34 deleteSession bool // close session and delete from pool 35 canRetry map[idempotency]bool 36 }{ 37 { 38 // retryer given unknown error - we will not operationStatus and will close session 39 err: fmt.Errorf("unknown error"), 40 backoff: backoff.TypeNoBackoff, 41 deleteSession: false, 42 canRetry: map[idempotency]bool{ 43 idempotent: false, 44 nonIdempotent: false, 45 }, 46 }, 47 { 48 // golang context deadline exceeded 49 err: context.DeadlineExceeded, 50 backoff: backoff.TypeNoBackoff, 51 deleteSession: false, 52 canRetry: map[idempotency]bool{ 53 idempotent: false, 54 nonIdempotent: false, 55 }, 56 }, 57 { 58 // golang context canceled 59 err: context.Canceled, 60 backoff: backoff.TypeNoBackoff, 61 deleteSession: false, 62 canRetry: map[idempotency]bool{ 63 idempotent: false, 64 nonIdempotent: false, 65 }, 66 }, 67 { 68 err: xerrors.Transport( 69 //nolint:staticcheck 70 // ignore SA1019 71 //nolint:nolintlint 72 grpc.ErrClientConnClosing, 73 ), 74 backoff: backoff.TypeFast, 75 deleteSession: true, 76 canRetry: map[idempotency]bool{ 77 idempotent: true, 78 nonIdempotent: false, 79 }, 80 }, 81 { 82 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Canceled, "")), 83 backoff: backoff.TypeFast, 84 deleteSession: true, 85 canRetry: map[idempotency]bool{ 86 idempotent: true, // if client context is not done 87 nonIdempotent: false, 88 }, 89 }, 90 { 91 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Unknown, "")), 92 backoff: backoff.TypeNoBackoff, 93 deleteSession: true, 94 canRetry: map[idempotency]bool{ 95 idempotent: false, 96 nonIdempotent: false, 97 }, 98 }, 99 { 100 err: xerrors.Transport(grpcStatus.Error(grpcCodes.InvalidArgument, "")), 101 backoff: backoff.TypeNoBackoff, 102 deleteSession: true, 103 canRetry: map[idempotency]bool{ 104 idempotent: false, 105 nonIdempotent: false, 106 }, 107 }, 108 { 109 err: xerrors.Transport(grpcStatus.Error(grpcCodes.DeadlineExceeded, "")), 110 backoff: backoff.TypeFast, 111 deleteSession: true, 112 canRetry: map[idempotency]bool{ 113 idempotent: true, // if client context is not done 114 nonIdempotent: false, 115 }, 116 }, 117 { 118 err: xerrors.Transport(grpcStatus.Error(grpcCodes.NotFound, "")), 119 backoff: backoff.TypeNoBackoff, 120 deleteSession: true, 121 canRetry: map[idempotency]bool{ 122 idempotent: false, 123 nonIdempotent: false, 124 }, 125 }, 126 { 127 err: xerrors.Transport(grpcStatus.Error(grpcCodes.AlreadyExists, "")), 128 backoff: backoff.TypeNoBackoff, 129 deleteSession: true, 130 canRetry: map[idempotency]bool{ 131 idempotent: false, 132 nonIdempotent: false, 133 }, 134 }, 135 { 136 err: xerrors.Transport(grpcStatus.Error(grpcCodes.PermissionDenied, "")), 137 backoff: backoff.TypeNoBackoff, 138 deleteSession: true, 139 canRetry: map[idempotency]bool{ 140 idempotent: false, 141 nonIdempotent: false, 142 }, 143 }, 144 { 145 err: xerrors.Transport(grpcStatus.Error(grpcCodes.ResourceExhausted, "")), 146 backoff: backoff.TypeSlow, 147 deleteSession: false, 148 canRetry: map[idempotency]bool{ 149 idempotent: true, 150 nonIdempotent: true, 151 }, 152 }, 153 { 154 err: xerrors.Transport(grpcStatus.Error(grpcCodes.FailedPrecondition, "")), 155 backoff: backoff.TypeNoBackoff, 156 deleteSession: true, 157 canRetry: map[idempotency]bool{ 158 idempotent: false, 159 nonIdempotent: false, 160 }, 161 }, 162 { 163 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Aborted, "")), 164 backoff: backoff.TypeNoBackoff, 165 deleteSession: true, 166 canRetry: map[idempotency]bool{ 167 idempotent: true, 168 nonIdempotent: true, 169 }, 170 }, 171 { 172 err: xerrors.Transport(grpcStatus.Error(grpcCodes.OutOfRange, "")), 173 backoff: backoff.TypeNoBackoff, 174 deleteSession: false, 175 canRetry: map[idempotency]bool{ 176 idempotent: false, 177 nonIdempotent: false, 178 }, 179 }, 180 { 181 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Unimplemented, "")), 182 backoff: backoff.TypeNoBackoff, 183 deleteSession: true, 184 canRetry: map[idempotency]bool{ 185 idempotent: false, 186 nonIdempotent: false, 187 }, 188 }, 189 { 190 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Internal, "")), 191 backoff: backoff.TypeFast, 192 deleteSession: true, 193 canRetry: map[idempotency]bool{ 194 idempotent: true, 195 nonIdempotent: false, 196 }, 197 }, 198 { 199 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Unavailable, "")), 200 backoff: backoff.TypeFast, 201 deleteSession: true, 202 canRetry: map[idempotency]bool{ 203 idempotent: true, 204 nonIdempotent: false, 205 }, 206 }, 207 { 208 err: xerrors.Retryable( 209 xerrors.Transport(grpcStatus.Error(grpcCodes.Unavailable, "")), 210 xerrors.WithBackoff(backoff.TypeFast), 211 xerrors.WithDeleteSession(), 212 ), 213 backoff: backoff.TypeFast, 214 deleteSession: true, 215 canRetry: map[idempotency]bool{ 216 idempotent: true, 217 nonIdempotent: true, 218 }, 219 }, 220 { 221 err: xerrors.Retryable( 222 grpcStatus.Error(grpcCodes.Unavailable, ""), 223 xerrors.WithBackoff(backoff.TypeFast), 224 xerrors.WithDeleteSession(), 225 ), 226 backoff: backoff.TypeFast, 227 deleteSession: true, 228 canRetry: map[idempotency]bool{ 229 idempotent: true, 230 nonIdempotent: true, 231 }, 232 }, 233 { 234 err: xerrors.Transport(grpcStatus.Error(grpcCodes.DataLoss, "")), 235 backoff: backoff.TypeNoBackoff, 236 deleteSession: true, 237 canRetry: map[idempotency]bool{ 238 idempotent: false, 239 nonIdempotent: false, 240 }, 241 }, 242 { 243 err: xerrors.Transport(grpcStatus.Error(grpcCodes.Unauthenticated, "")), 244 backoff: backoff.TypeNoBackoff, 245 deleteSession: true, 246 canRetry: map[idempotency]bool{ 247 idempotent: false, 248 nonIdempotent: false, 249 }, 250 }, 251 { 252 err: xerrors.Operation( 253 xerrors.WithStatusCode(Ydb.StatusIds_STATUS_CODE_UNSPECIFIED), 254 ), 255 backoff: backoff.TypeNoBackoff, 256 deleteSession: false, 257 canRetry: map[idempotency]bool{ 258 idempotent: false, 259 nonIdempotent: false, 260 }, 261 }, 262 { 263 err: xerrors.Operation( 264 xerrors.WithStatusCode(Ydb.StatusIds_BAD_REQUEST), 265 ), 266 backoff: backoff.TypeNoBackoff, 267 deleteSession: false, 268 canRetry: map[idempotency]bool{ 269 idempotent: false, 270 nonIdempotent: false, 271 }, 272 }, 273 { 274 err: xerrors.Operation( 275 xerrors.WithStatusCode(Ydb.StatusIds_UNAUTHORIZED), 276 ), 277 backoff: backoff.TypeNoBackoff, 278 deleteSession: false, 279 canRetry: map[idempotency]bool{ 280 idempotent: false, 281 nonIdempotent: false, 282 }, 283 }, 284 { 285 err: xerrors.Operation( 286 xerrors.WithStatusCode(Ydb.StatusIds_INTERNAL_ERROR), 287 ), 288 backoff: backoff.TypeNoBackoff, 289 deleteSession: false, 290 canRetry: map[idempotency]bool{ 291 idempotent: false, 292 nonIdempotent: false, 293 }, 294 }, 295 { 296 err: xerrors.Operation( 297 xerrors.WithStatusCode(Ydb.StatusIds_ABORTED), 298 ), 299 backoff: backoff.TypeFast, 300 deleteSession: false, 301 canRetry: map[idempotency]bool{ 302 idempotent: true, 303 nonIdempotent: true, 304 }, 305 }, 306 { 307 err: xerrors.Operation( 308 xerrors.WithStatusCode(Ydb.StatusIds_UNAVAILABLE), 309 ), 310 backoff: backoff.TypeFast, 311 deleteSession: false, 312 canRetry: map[idempotency]bool{ 313 idempotent: true, 314 nonIdempotent: true, 315 }, 316 }, 317 { 318 err: xerrors.Operation( 319 xerrors.WithStatusCode(Ydb.StatusIds_OVERLOADED), 320 ), 321 backoff: backoff.TypeSlow, 322 deleteSession: false, 323 canRetry: map[idempotency]bool{ 324 idempotent: true, 325 nonIdempotent: true, 326 }, 327 }, 328 { 329 err: xerrors.Operation( 330 xerrors.WithStatusCode(Ydb.StatusIds_SCHEME_ERROR), 331 ), 332 backoff: backoff.TypeNoBackoff, 333 deleteSession: false, 334 canRetry: map[idempotency]bool{ 335 idempotent: false, 336 nonIdempotent: false, 337 }, 338 }, 339 { 340 err: xerrors.Operation( 341 xerrors.WithStatusCode(Ydb.StatusIds_GENERIC_ERROR), 342 ), 343 backoff: backoff.TypeNoBackoff, 344 deleteSession: false, 345 canRetry: map[idempotency]bool{ 346 idempotent: false, 347 nonIdempotent: false, 348 }, 349 }, 350 { 351 err: xerrors.Operation( 352 xerrors.WithStatusCode(Ydb.StatusIds_TIMEOUT), 353 ), 354 backoff: backoff.TypeNoBackoff, 355 deleteSession: false, 356 canRetry: map[idempotency]bool{ 357 idempotent: false, 358 nonIdempotent: false, 359 }, 360 }, 361 { 362 err: xerrors.Operation( 363 xerrors.WithStatusCode(Ydb.StatusIds_BAD_SESSION), 364 ), 365 backoff: backoff.TypeNoBackoff, 366 deleteSession: true, 367 canRetry: map[idempotency]bool{ 368 idempotent: true, 369 nonIdempotent: true, 370 }, 371 }, 372 { 373 err: xerrors.Operation( 374 xerrors.WithStatusCode(Ydb.StatusIds_PRECONDITION_FAILED), 375 ), 376 backoff: backoff.TypeNoBackoff, 377 deleteSession: false, 378 canRetry: map[idempotency]bool{ 379 idempotent: false, 380 nonIdempotent: false, 381 }, 382 }, 383 { 384 err: xerrors.Operation( 385 xerrors.WithStatusCode(Ydb.StatusIds_ALREADY_EXISTS), 386 ), 387 backoff: backoff.TypeNoBackoff, 388 deleteSession: false, 389 canRetry: map[idempotency]bool{ 390 idempotent: false, 391 nonIdempotent: false, 392 }, 393 }, 394 { 395 err: xerrors.Operation( 396 xerrors.WithStatusCode(Ydb.StatusIds_NOT_FOUND), 397 ), 398 backoff: backoff.TypeNoBackoff, 399 deleteSession: false, 400 canRetry: map[idempotency]bool{ 401 idempotent: false, 402 nonIdempotent: false, 403 }, 404 }, 405 { 406 err: xerrors.Operation( 407 xerrors.WithStatusCode(Ydb.StatusIds_SESSION_EXPIRED), 408 ), 409 backoff: backoff.TypeNoBackoff, 410 deleteSession: true, 411 canRetry: map[idempotency]bool{ 412 idempotent: true, 413 nonIdempotent: false, 414 }, 415 }, 416 { 417 err: xerrors.Operation( 418 xerrors.WithStatusCode(Ydb.StatusIds_CANCELLED), 419 ), 420 backoff: backoff.TypeFast, 421 deleteSession: false, 422 canRetry: map[idempotency]bool{ 423 idempotent: false, 424 nonIdempotent: false, 425 }, 426 }, 427 { 428 err: xerrors.Operation( 429 xerrors.WithStatusCode(Ydb.StatusIds_UNDETERMINED), 430 ), 431 backoff: backoff.TypeFast, 432 deleteSession: false, 433 canRetry: map[idempotency]bool{ 434 idempotent: true, 435 nonIdempotent: false, 436 }, 437 }, 438 { 439 err: xerrors.Operation( 440 xerrors.WithStatusCode(Ydb.StatusIds_UNSUPPORTED), 441 ), 442 backoff: backoff.TypeNoBackoff, 443 deleteSession: false, 444 canRetry: map[idempotency]bool{ 445 idempotent: false, 446 nonIdempotent: false, 447 }, 448 }, 449 { 450 err: xerrors.Operation( 451 xerrors.WithStatusCode(Ydb.StatusIds_SESSION_BUSY), 452 ), 453 backoff: backoff.TypeFast, 454 deleteSession: true, 455 canRetry: map[idempotency]bool{ 456 idempotent: true, 457 nonIdempotent: true, 458 }, 459 }, 460 }