github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/message/error.go (about) 1 // Copyright 2020 DataStax 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package message 16 17 import ( 18 "fmt" 19 "io" 20 21 "github.com/datastax/go-cassandra-native-protocol/primitive" 22 ) 23 24 type Error interface { 25 Message 26 GetErrorCode() primitive.ErrorCode 27 GetErrorMessage() string 28 } 29 30 // SERVER ERROR 31 32 // ServerError is a server error response. 33 // +k8s:deepcopy-gen=true 34 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 35 type ServerError struct { 36 ErrorMessage string 37 } 38 39 func (m *ServerError) IsResponse() bool { 40 return true 41 } 42 43 func (m *ServerError) GetOpCode() primitive.OpCode { 44 return primitive.OpCodeError 45 } 46 47 func (m *ServerError) GetErrorCode() primitive.ErrorCode { 48 return primitive.ErrorCodeServerError 49 } 50 51 func (m *ServerError) GetErrorMessage() string { 52 return m.ErrorMessage 53 } 54 55 func (m *ServerError) String() string { 56 return fmt.Sprintf("ERROR SERVER ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 57 } 58 59 // PROTOCOL ERROR 60 61 // ProtocolError is a protocol error response. 62 // +k8s:deepcopy-gen=true 63 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 64 type ProtocolError struct { 65 ErrorMessage string 66 } 67 68 func (m *ProtocolError) IsResponse() bool { 69 return true 70 } 71 72 func (m *ProtocolError) GetOpCode() primitive.OpCode { 73 return primitive.OpCodeError 74 } 75 76 func (m *ProtocolError) GetErrorCode() primitive.ErrorCode { 77 return primitive.ErrorCodeProtocolError 78 } 79 80 func (m *ProtocolError) GetErrorMessage() string { 81 return m.ErrorMessage 82 } 83 84 func (m *ProtocolError) String() string { 85 return fmt.Sprintf("ERROR PROTOCOL ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 86 } 87 88 // AUTHENTICATION ERROR 89 90 // AuthenticationError is an authentication error response. 91 // +k8s:deepcopy-gen=true 92 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 93 type AuthenticationError struct { 94 ErrorMessage string 95 } 96 97 func (m *AuthenticationError) IsResponse() bool { 98 return true 99 } 100 101 func (m *AuthenticationError) GetOpCode() primitive.OpCode { 102 return primitive.OpCodeError 103 } 104 105 func (m *AuthenticationError) GetErrorCode() primitive.ErrorCode { 106 return primitive.ErrorCodeAuthenticationError 107 } 108 109 func (m *AuthenticationError) GetErrorMessage() string { 110 return m.ErrorMessage 111 } 112 113 func (m *AuthenticationError) String() string { 114 return fmt.Sprintf("ERROR AUTHENTICATION ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 115 } 116 117 // OVERLOADED 118 119 // Overloaded is an error response sent when the coordinator is overloaded. 120 // +k8s:deepcopy-gen=true 121 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 122 type Overloaded struct { 123 ErrorMessage string 124 } 125 126 func (m *Overloaded) IsResponse() bool { 127 return true 128 } 129 130 func (m *Overloaded) GetOpCode() primitive.OpCode { 131 return primitive.OpCodeError 132 } 133 134 func (m *Overloaded) GetErrorCode() primitive.ErrorCode { 135 return primitive.ErrorCodeOverloaded 136 } 137 138 func (m *Overloaded) GetErrorMessage() string { 139 return m.ErrorMessage 140 } 141 142 func (m *Overloaded) String() string { 143 return fmt.Sprintf("ERROR OVERLOADED (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 144 } 145 146 // IS BOOTSTRAPPING 147 148 // IsBootstrapping is an error response sent when the coordinator is bootstrapping. 149 // +k8s:deepcopy-gen=true 150 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 151 type IsBootstrapping struct { 152 ErrorMessage string 153 } 154 155 func (m *IsBootstrapping) IsResponse() bool { 156 return true 157 } 158 159 func (m *IsBootstrapping) GetOpCode() primitive.OpCode { 160 return primitive.OpCodeError 161 } 162 163 func (m *IsBootstrapping) GetErrorCode() primitive.ErrorCode { 164 return primitive.ErrorCodeIsBootstrapping 165 } 166 167 func (m *IsBootstrapping) GetErrorMessage() string { 168 return m.ErrorMessage 169 } 170 171 func (m *IsBootstrapping) String() string { 172 return fmt.Sprintf("ERROR IS BOOTSTRAPPING (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 173 } 174 175 // TRUNCATE ERROR 176 177 // TruncateError is an error response notifying that a TRUNCATE statement failed. 178 // +k8s:deepcopy-gen=true 179 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 180 type TruncateError struct { 181 ErrorMessage string 182 } 183 184 func (m *TruncateError) IsResponse() bool { 185 return true 186 } 187 188 func (m *TruncateError) GetOpCode() primitive.OpCode { 189 return primitive.OpCodeError 190 } 191 192 func (m *TruncateError) GetErrorCode() primitive.ErrorCode { 193 return primitive.ErrorCodeTruncateError 194 } 195 196 func (m *TruncateError) GetErrorMessage() string { 197 return m.ErrorMessage 198 } 199 200 func (m *TruncateError) String() string { 201 return fmt.Sprintf("ERROR TRUNCATE ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 202 } 203 204 // SYNTAX ERROR 205 206 // SyntaxError is an error response notifying that the query has a syntax error. 207 // +k8s:deepcopy-gen=true 208 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 209 type SyntaxError struct { 210 ErrorMessage string 211 } 212 213 func (m *SyntaxError) IsResponse() bool { 214 return true 215 } 216 217 func (m *SyntaxError) GetOpCode() primitive.OpCode { 218 return primitive.OpCodeError 219 } 220 221 func (m *SyntaxError) GetErrorCode() primitive.ErrorCode { 222 return primitive.ErrorCodeSyntaxError 223 } 224 225 func (m *SyntaxError) GetErrorMessage() string { 226 return m.ErrorMessage 227 } 228 229 func (m *SyntaxError) String() string { 230 return fmt.Sprintf("ERROR SYNTAX ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 231 } 232 233 // UNAUTHORIZED 234 235 // Unauthorized is an error response notifying that the logged user is not authorized to perform the request. 236 // +k8s:deepcopy-gen=true 237 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 238 type Unauthorized struct { 239 ErrorMessage string 240 } 241 242 func (m *Unauthorized) IsResponse() bool { 243 return true 244 } 245 246 func (m *Unauthorized) GetOpCode() primitive.OpCode { 247 return primitive.OpCodeError 248 } 249 250 func (m *Unauthorized) GetErrorCode() primitive.ErrorCode { 251 return primitive.ErrorCodeUnauthorized 252 } 253 254 func (m *Unauthorized) GetErrorMessage() string { 255 return m.ErrorMessage 256 } 257 258 func (m *Unauthorized) String() string { 259 return fmt.Sprintf("ERROR UNAUTHORIZED (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 260 } 261 262 // INVALID 263 264 // Invalid is an error response sent when the query is syntactically correct but invalid. 265 // +k8s:deepcopy-gen=true 266 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 267 type Invalid struct { 268 ErrorMessage string 269 } 270 271 func (m *Invalid) IsResponse() bool { 272 return true 273 } 274 275 func (m *Invalid) GetOpCode() primitive.OpCode { 276 return primitive.OpCodeError 277 } 278 279 func (m *Invalid) GetErrorCode() primitive.ErrorCode { 280 return primitive.ErrorCodeInvalid 281 } 282 283 func (m *Invalid) GetErrorMessage() string { 284 return m.ErrorMessage 285 } 286 287 func (m *Invalid) String() string { 288 return fmt.Sprintf("ERROR INVALID (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 289 } 290 291 // CONFIG ERROR 292 293 // ConfigError is an error response sent when the query cannot be executed due to some configuration issue. 294 // +k8s:deepcopy-gen=true 295 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 296 type ConfigError struct { 297 ErrorMessage string 298 } 299 300 func (m *ConfigError) IsResponse() bool { 301 return true 302 } 303 304 func (m *ConfigError) GetOpCode() primitive.OpCode { 305 return primitive.OpCodeError 306 } 307 308 func (m *ConfigError) GetErrorCode() primitive.ErrorCode { 309 return primitive.ErrorCodeConfigError 310 } 311 312 func (m *ConfigError) GetErrorMessage() string { 313 return m.ErrorMessage 314 } 315 316 func (m *ConfigError) String() string { 317 return fmt.Sprintf("ERROR CONFIG ERROR (code=%v, msg=%v)", m.GetErrorCode(), m.ErrorMessage) 318 } 319 320 // UNAVAILABLE 321 322 // Unavailable is an error response sent when the coordinator knows that the consistency level cannot be fulfilled. 323 // +k8s:deepcopy-gen=true 324 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 325 type Unavailable struct { 326 ErrorMessage string 327 // The consistency level of the query that triggered the exception. 328 Consistency primitive.ConsistencyLevel 329 // The number of nodes that should be alive to respect Consistency. 330 Required int32 331 // The number of replicas that were known to be alive when the request was processed (since an 332 // unavailable exception has been triggered, Alive < Required). 333 Alive int32 334 } 335 336 func (m *Unavailable) IsResponse() bool { 337 return true 338 } 339 340 func (m *Unavailable) GetOpCode() primitive.OpCode { 341 return primitive.OpCodeError 342 } 343 344 func (m *Unavailable) GetErrorCode() primitive.ErrorCode { 345 return primitive.ErrorCodeUnavailable 346 } 347 348 func (m *Unavailable) GetErrorMessage() string { 349 return m.ErrorMessage 350 } 351 352 func (m *Unavailable) String() string { 353 return fmt.Sprintf( 354 "ERROR UNAVAILABLE (code=%v, msg=%v, cl=%v, required=%v, alive=%v)", 355 m.GetErrorCode(), 356 m.GetErrorMessage(), 357 m.Consistency, 358 m.Required, 359 m.Alive, 360 ) 361 } 362 363 // READ TIMEOUT 364 365 // ReadTimeout is an error response sent when the coordinator does not receive enough responses from replicas for a read 366 // query. 367 // +k8s:deepcopy-gen=true 368 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 369 type ReadTimeout struct { 370 ErrorMessage string 371 // The consistency level of the query that triggered the exception. 372 Consistency primitive.ConsistencyLevel 373 // The number of nodes having answered the request. 374 Received int32 375 // The number of replicas whose response is required to achieve Consistency. 376 // It is possible to have Received >= BlockFor if DataPresent is false. Also 377 // in the (unlikely) case where Consistency is achieved but the coordinator node 378 // times out while waiting for read-repair acknowledgement. 379 BlockFor int32 380 // Whether the replica that was asked for data responded. 381 DataPresent bool 382 } 383 384 func (m *ReadTimeout) IsResponse() bool { 385 return true 386 } 387 388 func (m *ReadTimeout) GetOpCode() primitive.OpCode { 389 return primitive.OpCodeError 390 } 391 392 func (m *ReadTimeout) GetErrorCode() primitive.ErrorCode { 393 return primitive.ErrorCodeReadTimeout 394 } 395 396 func (m *ReadTimeout) GetErrorMessage() string { 397 return m.ErrorMessage 398 } 399 400 func (m *ReadTimeout) String() string { 401 return fmt.Sprintf( 402 "ERROR READ TIMEOUT (code=%v, msg=%v, cl=%v, received=%v, blockfor=%v, data=%v)", 403 m.GetErrorCode(), 404 m.GetErrorMessage(), 405 m.Consistency, 406 m.Received, 407 m.BlockFor, 408 m.DataPresent, 409 ) 410 } 411 412 // WRITE TIMEOUT 413 414 // WriteTimeout is an error response sent when the coordinator does not receive enough responses from replicas for a 415 // write query. 416 // +k8s:deepcopy-gen=true 417 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 418 type WriteTimeout struct { 419 ErrorMessage string 420 // The consistency level of the query that triggered the exception. 421 Consistency primitive.ConsistencyLevel 422 // The number of nodes having answered the request. 423 Received int32 424 // The number of replicas whose response is required to achieve Consistency. 425 BlockFor int32 426 // The type of the write that failed. 427 WriteType primitive.WriteType 428 // The number of contentions occurred during the CAS operation. This field is only present when WriteType is "CAS". 429 Contentions uint16 430 } 431 432 func (m *WriteTimeout) IsResponse() bool { 433 return true 434 } 435 436 func (m *WriteTimeout) GetOpCode() primitive.OpCode { 437 return primitive.OpCodeError 438 } 439 440 func (m *WriteTimeout) GetErrorCode() primitive.ErrorCode { 441 return primitive.ErrorCodeWriteTimeout 442 } 443 444 func (m *WriteTimeout) GetErrorMessage() string { 445 return m.ErrorMessage 446 } 447 448 func (m *WriteTimeout) String() string { 449 return fmt.Sprintf( 450 "ERROR WRITE TIMEOUT (code=%v, msg=%v, cl=%v, received=%v, blockfor=%v, type=%v, contentions=%v)", 451 m.GetErrorCode(), 452 m.GetErrorMessage(), 453 m.Consistency, 454 m.Received, 455 m.BlockFor, 456 m.WriteType, 457 m.Contentions, 458 ) 459 } 460 461 // READ FAILURE 462 463 // ReadFailure is an error response sent when the coordinator receives a read failure from a replica. 464 // +k8s:deepcopy-gen=true 465 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 466 type ReadFailure struct { 467 ErrorMessage string 468 // The consistency level of the query that triggered the exception. 469 Consistency primitive.ConsistencyLevel 470 // The number of nodes having answered the request. 471 Received int32 472 // The number of replicas whose response is required to achieve Consistency. 473 BlockFor int32 474 // The number of nodes that experienced a failure while executing the request. 475 // Only filled when the protocol versions is < 5. 476 NumFailures int32 477 // A collection of endpoints with failure reason codes. Only filled when the protocol versions is >= 5, including 478 // DSE versions v1 and v2. 479 FailureReasons []*primitive.FailureReason 480 // Whether the replica that was asked for data responded. 481 DataPresent bool 482 } 483 484 func (m *ReadFailure) IsResponse() bool { 485 return true 486 } 487 488 func (m *ReadFailure) GetOpCode() primitive.OpCode { 489 return primitive.OpCodeError 490 } 491 492 func (m *ReadFailure) GetErrorCode() primitive.ErrorCode { 493 return primitive.ErrorCodeReadFailure 494 } 495 496 func (m *ReadFailure) GetErrorMessage() string { 497 return m.ErrorMessage 498 } 499 500 func (m *ReadFailure) String() string { 501 return fmt.Sprintf( 502 "ERROR READ FAILURE (code=%v, msg=%v, cl=%v, received=%v, blockfor=%v, data=%v)", 503 m.GetErrorCode(), 504 m.GetErrorMessage(), 505 m.Consistency, 506 m.Received, 507 m.BlockFor, 508 m.DataPresent, 509 ) 510 } 511 512 // WRITE FAILURE 513 514 // WriteFailure is an error response sent when the coordinator receives a write failure from a replica. 515 // +k8s:deepcopy-gen=true 516 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 517 type WriteFailure struct { 518 ErrorMessage string 519 // The consistency level of the query that triggered the exception. 520 Consistency primitive.ConsistencyLevel 521 // The number of nodes having answered the request. 522 Received int32 523 // The number of replicas whose response is required to achieve Consistency. 524 BlockFor int32 525 // The number of nodes that experienced a failure while executing the request. 526 // Only filled when the protocol versions is < 5. 527 NumFailures int32 528 // A collection of endpoints with failure reason codes. Only filled when the protocol versions is >= 5, including 529 // DSE versions v1 and v2. 530 FailureReasons []*primitive.FailureReason 531 // The type of the write that failed. 532 WriteType primitive.WriteType 533 } 534 535 func (m *WriteFailure) IsResponse() bool { 536 return true 537 } 538 539 func (m *WriteFailure) GetOpCode() primitive.OpCode { 540 return primitive.OpCodeError 541 } 542 543 func (m *WriteFailure) GetErrorCode() primitive.ErrorCode { 544 return primitive.ErrorCodeWriteFailure 545 } 546 547 func (m *WriteFailure) GetErrorMessage() string { 548 return m.ErrorMessage 549 } 550 551 func (m *WriteFailure) String() string { 552 return fmt.Sprintf( 553 "ERROR WRITE FAILURE (code=%v, msg=%v, cl=%v, received=%v, blockfor=%v, type=%v)", 554 m.GetErrorCode(), 555 m.GetErrorMessage(), 556 m.Consistency, 557 m.Received, 558 m.BlockFor, 559 m.WriteType, 560 ) 561 } 562 563 // FUNCTION FAILURE 564 565 // FunctionFailure is an error response sent when the coordinator receives an error from a replica while executing a 566 // function. 567 // +k8s:deepcopy-gen=true 568 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 569 type FunctionFailure struct { 570 ErrorMessage string 571 Keyspace string 572 Function string 573 Arguments []string 574 } 575 576 func (m *FunctionFailure) IsResponse() bool { 577 return true 578 } 579 580 func (m *FunctionFailure) GetOpCode() primitive.OpCode { 581 return primitive.OpCodeError 582 } 583 584 func (m *FunctionFailure) GetErrorCode() primitive.ErrorCode { 585 return primitive.ErrorCodeFunctionFailure 586 } 587 588 func (m *FunctionFailure) GetErrorMessage() string { 589 return m.ErrorMessage 590 } 591 592 func (m *FunctionFailure) String() string { 593 return fmt.Sprintf( 594 "ERROR FUNCTION FAILURE (code=%v, msg=%v, ks=%v, function=%v, args=%v)", 595 m.GetErrorCode(), 596 m.GetErrorMessage(), 597 m.Keyspace, 598 m.Function, 599 m.Arguments, 600 ) 601 } 602 603 // UNPREPARED 604 605 // Unprepared is an error response sent when an unprepared query execution is attempted. 606 // +k8s:deepcopy-gen=true 607 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 608 type Unprepared struct { 609 ErrorMessage string 610 Id []byte 611 } 612 613 func (m *Unprepared) IsResponse() bool { 614 return true 615 } 616 617 func (m *Unprepared) GetOpCode() primitive.OpCode { 618 return primitive.OpCodeError 619 } 620 621 func (m *Unprepared) GetErrorCode() primitive.ErrorCode { 622 return primitive.ErrorCodeUnprepared 623 } 624 625 func (m *Unprepared) GetErrorMessage() string { 626 return m.ErrorMessage 627 } 628 629 func (m *Unprepared) String() string { 630 return fmt.Sprintf( 631 "ERROR UNPREPARED (code=%v, msg=%v, id=%v)", 632 m.GetErrorCode(), 633 m.GetErrorMessage(), 634 m.Id, 635 ) 636 } 637 638 // ALREADY EXISTS 639 640 // AlreadyExists is an error response sent when the creation of a schema object fails because the object already exists. 641 // +k8s:deepcopy-gen=true 642 // +k8s:deepcopy-gen:interfaces=github.com/datastax/go-cassandra-native-protocol/message.Message 643 type AlreadyExists struct { 644 ErrorMessage string 645 Keyspace string 646 Table string 647 } 648 649 func (m *AlreadyExists) IsResponse() bool { 650 return true 651 } 652 653 func (m *AlreadyExists) GetOpCode() primitive.OpCode { 654 return primitive.OpCodeError 655 } 656 657 func (m *AlreadyExists) GetErrorCode() primitive.ErrorCode { 658 return primitive.ErrorCodeAlreadyExists 659 } 660 661 func (m *AlreadyExists) GetErrorMessage() string { 662 return m.ErrorMessage 663 } 664 665 func (m *AlreadyExists) String() string { 666 return fmt.Sprintf( 667 "ERROR ALREADY EXISTS (code=%v, msg=%v, ks=%v, table=%v)", 668 m.GetErrorCode(), 669 m.GetErrorMessage(), 670 m.Keyspace, 671 m.Table, 672 ) 673 } 674 675 // CODEC 676 677 type errorCodec struct{} 678 679 func (c *errorCodec) Encode(msg Message, dest io.Writer, version primitive.ProtocolVersion) (err error) { 680 errMsg, ok := msg.(Error) 681 if !ok { 682 return fmt.Errorf("expected Error, got %T", msg) 683 } 684 if err = primitive.WriteInt(int32(errMsg.GetErrorCode()), dest); err != nil { 685 return fmt.Errorf("cannot write ERROR code: %w", err) 686 } 687 if err = primitive.WriteString(errMsg.GetErrorMessage(), dest); err != nil { 688 return fmt.Errorf("cannot write ERROR message: %w", err) 689 } 690 switch errMsg.GetErrorCode() { 691 case primitive.ErrorCodeServerError: 692 case primitive.ErrorCodeProtocolError: 693 case primitive.ErrorCodeAuthenticationError: 694 case primitive.ErrorCodeOverloaded: 695 case primitive.ErrorCodeIsBootstrapping: 696 case primitive.ErrorCodeTruncateError: 697 case primitive.ErrorCodeSyntaxError: 698 case primitive.ErrorCodeUnauthorized: 699 case primitive.ErrorCodeInvalid: 700 case primitive.ErrorCodeConfigError: 701 702 case primitive.ErrorCodeUnavailable: 703 unavailable, ok := errMsg.(*Unavailable) 704 if !ok { 705 return fmt.Errorf("expected *message.Unavailable, got %T", msg) 706 } 707 if err = primitive.WriteShort(uint16(unavailable.Consistency), dest); err != nil { 708 return fmt.Errorf("cannot write ERROR UNAVAILABLE consistency: %w", err) 709 } else if err = primitive.WriteInt(unavailable.Required, dest); err != nil { 710 return fmt.Errorf("cannot write ERROR UNAVAILABLE required: %w", err) 711 } else if err = primitive.WriteInt(unavailable.Alive, dest); err != nil { 712 return fmt.Errorf("cannot write ERROR UNAVAILABLE alive: %w", err) 713 } 714 715 case primitive.ErrorCodeReadTimeout: 716 readTimeout, ok := errMsg.(*ReadTimeout) 717 if !ok { 718 return fmt.Errorf("expected *message.ReadTimeout, got %T", msg) 719 } 720 if err = primitive.WriteShort(uint16(readTimeout.Consistency), dest); err != nil { 721 return fmt.Errorf("cannot write ERROR READ TIMEOUT consistency: %w", err) 722 } else if err = primitive.WriteInt(readTimeout.Received, dest); err != nil { 723 return fmt.Errorf("cannot write ERROR READ TIMEOUT received: %w", err) 724 } else if err = primitive.WriteInt(readTimeout.BlockFor, dest); err != nil { 725 return fmt.Errorf("cannot write ERROR READ TIMEOUT block for: %w", err) 726 } 727 if readTimeout.DataPresent { 728 err = primitive.WriteByte(1, dest) 729 } else { 730 err = primitive.WriteByte(0, dest) 731 } 732 if err != nil { 733 return fmt.Errorf("cannot write ERROR READ TIMEOUT data present: %w", err) 734 } 735 736 case primitive.ErrorCodeWriteTimeout: 737 writeTimeout, ok := errMsg.(*WriteTimeout) 738 if !ok { 739 return fmt.Errorf("expected *message.WriteTimeout, got %T", msg) 740 } 741 if err = primitive.WriteShort(uint16(writeTimeout.Consistency), dest); err != nil { 742 return fmt.Errorf("cannot write ERROR WRITE TIMEOUT consistency: %w", err) 743 } else if err = primitive.WriteInt(writeTimeout.Received, dest); err != nil { 744 return fmt.Errorf("cannot write ERROR WRITE TIMEOUT received: %w", err) 745 } else if err = primitive.WriteInt(writeTimeout.BlockFor, dest); err != nil { 746 return fmt.Errorf("cannot write ERROR WRITE TIMEOUT block for: %w", err) 747 } else if err = primitive.WriteString(string(writeTimeout.WriteType), dest); err != nil { 748 return fmt.Errorf("cannot write ERROR WRITE TIMEOUT write type: %w", err) 749 } else if version.SupportsWriteTimeoutContentions() && writeTimeout.WriteType == primitive.WriteTypeCas { 750 if err = primitive.WriteShort(uint16(writeTimeout.Contentions), dest); err != nil { 751 return fmt.Errorf("cannot write ERROR WRITE TIMEOUT contentions: %w", err) 752 } 753 } 754 755 case primitive.ErrorCodeReadFailure: 756 readFailure, ok := errMsg.(*ReadFailure) 757 if !ok { 758 return fmt.Errorf("expected *message.ReadFailure, got %T", msg) 759 } 760 if err = primitive.WriteShort(uint16(readFailure.Consistency), dest); err != nil { 761 return fmt.Errorf("cannot write ERROR READ FAILURE consistency: %w", err) 762 } else if err = primitive.WriteInt(readFailure.Received, dest); err != nil { 763 return fmt.Errorf("cannot write ERROR READ FAILURE received: %w", err) 764 } else if err = primitive.WriteInt(readFailure.BlockFor, dest); err != nil { 765 return fmt.Errorf("cannot write ERROR READ FAILURE block for: %w", err) 766 } 767 if version.SupportsReadWriteFailureReasonMap() { 768 if err = primitive.WriteReasonMap(readFailure.FailureReasons, dest); err != nil { 769 return fmt.Errorf("cannot write ERROR READ FAILURE reason map: %w", err) 770 } 771 } else { 772 if err = primitive.WriteInt(readFailure.NumFailures, dest); err != nil { 773 return fmt.Errorf("cannot write ERROR READ FAILURE num failures: %w", err) 774 } 775 } 776 if readFailure.DataPresent { 777 err = primitive.WriteByte(1, dest) 778 } else { 779 err = primitive.WriteByte(0, dest) 780 } 781 if err != nil { 782 return fmt.Errorf("cannot write ERROR READ FAILURE data present: %w", err) 783 } 784 785 case primitive.ErrorCodeWriteFailure: 786 writeFailure, ok := errMsg.(*WriteFailure) 787 if !ok { 788 return fmt.Errorf("expected *message.WriteFailure, got %T", msg) 789 } 790 if err = primitive.WriteShort(uint16(writeFailure.Consistency), dest); err != nil { 791 return fmt.Errorf("cannot write ERROR WRITE FAILURE consistency: %w", err) 792 } else if err = primitive.WriteInt(writeFailure.Received, dest); err != nil { 793 return fmt.Errorf("cannot write ERROR WRITE FAILURE received: %w", err) 794 } else if err = primitive.WriteInt(writeFailure.BlockFor, dest); err != nil { 795 return fmt.Errorf("cannot write ERROR WRITE FAILURE block for: %w", err) 796 } 797 if version.SupportsReadWriteFailureReasonMap() { 798 if err = primitive.WriteReasonMap(writeFailure.FailureReasons, dest); err != nil { 799 return fmt.Errorf("cannot write ERROR WRITE FAILURE reason map: %w", err) 800 } 801 } else { 802 if err = primitive.WriteInt(writeFailure.NumFailures, dest); err != nil { 803 return fmt.Errorf("cannot write ERROR WRITE FAILURE num failures: %w", err) 804 } 805 } 806 if err = primitive.WriteString(string(writeFailure.WriteType), dest); err != nil { 807 return fmt.Errorf("cannot write ERROR WRITE FAILURE write type: %w", err) 808 } 809 810 case primitive.ErrorCodeFunctionFailure: 811 functionFailure, ok := errMsg.(*FunctionFailure) 812 if !ok { 813 return fmt.Errorf("expected *message.FunctionFailure, got %T", msg) 814 } 815 if err = primitive.WriteString(functionFailure.Keyspace, dest); err != nil { 816 return fmt.Errorf("cannot write ERROR FUNCTION FAILURE keyspace: %w", err) 817 } else if err = primitive.WriteString(functionFailure.Function, dest); err != nil { 818 return fmt.Errorf("cannot write ERROR FUNCTION FAILURE function: %w", err) 819 } else if err = primitive.WriteStringList(functionFailure.Arguments, dest); err != nil { 820 return fmt.Errorf("cannot write ERROR FUNCTION FAILURE arguments: %w", err) 821 } 822 823 case primitive.ErrorCodeAlreadyExists: 824 alreadyExists, ok := errMsg.(*AlreadyExists) 825 if !ok { 826 return fmt.Errorf("expected *message.AlreadyExists, got %T", msg) 827 } 828 if err = primitive.WriteString(alreadyExists.Keyspace, dest); err != nil { 829 return fmt.Errorf("cannot write ERROR ALREADY EXISTS keyspace: %w", err) 830 } else if err = primitive.WriteString(alreadyExists.Table, dest); err != nil { 831 return fmt.Errorf("cannot write ERROR ALREADY EXISTS table: %w", err) 832 } 833 834 case primitive.ErrorCodeUnprepared: 835 unprepared, ok := errMsg.(*Unprepared) 836 if !ok { 837 return fmt.Errorf("expected *message.Unprepared, got %T", msg) 838 } 839 if err = primitive.WriteShortBytes(unprepared.Id, dest); err != nil { 840 return fmt.Errorf("cannot write ERROR UNPREPARED id: %w", err) 841 } 842 843 default: 844 err = fmt.Errorf("unknown ERROR code: %v", errMsg.GetErrorCode()) 845 } 846 return err 847 } 848 849 func (c *errorCodec) EncodedLength(msg Message, version primitive.ProtocolVersion) (length int, err error) { 850 errMsg := msg.(Error) 851 length += primitive.LengthOfInt // error code 852 length += primitive.LengthOfString(errMsg.GetErrorMessage()) 853 switch errMsg.GetErrorCode() { 854 case primitive.ErrorCodeServerError: 855 case primitive.ErrorCodeProtocolError: 856 case primitive.ErrorCodeAuthenticationError: 857 case primitive.ErrorCodeOverloaded: 858 case primitive.ErrorCodeIsBootstrapping: 859 case primitive.ErrorCodeTruncateError: 860 case primitive.ErrorCodeSyntaxError: 861 case primitive.ErrorCodeUnauthorized: 862 case primitive.ErrorCodeInvalid: 863 case primitive.ErrorCodeConfigError: 864 865 case primitive.ErrorCodeUnavailable: 866 length += primitive.LengthOfShort // consistency 867 length += primitive.LengthOfInt // required 868 length += primitive.LengthOfInt // alive 869 870 case primitive.ErrorCodeReadTimeout: 871 length += primitive.LengthOfShort // consistency 872 length += primitive.LengthOfInt // received 873 length += primitive.LengthOfInt // block for 874 length += primitive.LengthOfByte // data present 875 876 case primitive.ErrorCodeWriteTimeout: 877 writeTimeout, ok := errMsg.(*WriteTimeout) 878 if !ok { 879 return -1, fmt.Errorf("expected *message.WriteTimeout, got %T", msg) 880 } 881 length += primitive.LengthOfShort // consistency 882 length += primitive.LengthOfInt // received 883 length += primitive.LengthOfInt // block for 884 length += primitive.LengthOfString(string(writeTimeout.WriteType)) // write type 885 if version.SupportsWriteTimeoutContentions() && writeTimeout.WriteType == primitive.WriteTypeCas { 886 length += primitive.LengthOfShort // contentions 887 } 888 889 case primitive.ErrorCodeReadFailure: 890 length += primitive.LengthOfShort // consistency 891 length += primitive.LengthOfInt // received 892 length += primitive.LengthOfInt // block for 893 length += primitive.LengthOfByte // data present 894 if version.SupportsReadWriteFailureReasonMap() { 895 readFailure, ok := errMsg.(*ReadFailure) 896 if !ok { 897 return -1, fmt.Errorf("expected *message.ReadFailure, got %T", msg) 898 } 899 if reasonMapLength, err := primitive.LengthOfReasonMap(readFailure.FailureReasons); err != nil { 900 return -1, fmt.Errorf("cannot compute length of ERROR READ FAILURE rason map: %w", err) 901 } else { 902 return length + reasonMapLength, nil 903 } 904 } else { 905 return length + primitive.LengthOfInt /* num failures */, nil 906 } 907 908 case primitive.ErrorCodeWriteFailure: 909 writeFailure, ok := errMsg.(*WriteFailure) 910 if !ok { 911 return -1, fmt.Errorf("expected *message.WriteFailure, got %T", msg) 912 } 913 length += primitive.LengthOfShort // consistency 914 length += primitive.LengthOfInt // received 915 length += primitive.LengthOfInt // block for 916 length += primitive.LengthOfString(string(writeFailure.WriteType)) // write type 917 if version.SupportsReadWriteFailureReasonMap() { 918 if reasonMapLength, err := primitive.LengthOfReasonMap(writeFailure.FailureReasons); err != nil { 919 return -1, fmt.Errorf("cannot compute length of ERROR WRITE FAILURE rason map: %w", err) 920 } else { 921 return length + reasonMapLength, nil 922 } 923 } else { 924 return length + primitive.LengthOfInt /* num failures */, nil 925 } 926 927 case primitive.ErrorCodeFunctionFailure: 928 functionFailure := errMsg.(*FunctionFailure) 929 length += primitive.LengthOfString(functionFailure.Keyspace) 930 length += primitive.LengthOfString(functionFailure.Function) 931 length += primitive.LengthOfStringList(functionFailure.Arguments) 932 933 case primitive.ErrorCodeAlreadyExists: 934 alreadyExists := errMsg.(*AlreadyExists) 935 length += primitive.LengthOfString(alreadyExists.Keyspace) 936 length += primitive.LengthOfString(alreadyExists.Table) 937 938 case primitive.ErrorCodeUnprepared: 939 unprepared := errMsg.(*Unprepared) 940 length += primitive.LengthOfShortBytes(unprepared.Id) 941 942 default: 943 err = fmt.Errorf("unknown ERROR code: %v", errMsg.GetErrorCode()) 944 945 } 946 return 947 } 948 949 func (c *errorCodec) Decode(source io.Reader, version primitive.ProtocolVersion) (msg Message, err error) { 950 var code int32 951 if code, err = primitive.ReadInt(source); err != nil { 952 return nil, fmt.Errorf("cannot read ERROR code: %w", err) 953 } 954 var errorMsg string 955 if errorMsg, err = primitive.ReadString(source); err != nil { 956 return nil, fmt.Errorf("cannot read ERROR message: %w", err) 957 } 958 switch primitive.ErrorCode(code) { 959 case primitive.ErrorCodeServerError: 960 return &ServerError{errorMsg}, nil 961 case primitive.ErrorCodeProtocolError: 962 return &ProtocolError{errorMsg}, nil 963 case primitive.ErrorCodeAuthenticationError: 964 return &AuthenticationError{errorMsg}, nil 965 case primitive.ErrorCodeOverloaded: 966 return &Overloaded{errorMsg}, nil 967 case primitive.ErrorCodeIsBootstrapping: 968 return &IsBootstrapping{errorMsg}, nil 969 case primitive.ErrorCodeTruncateError: 970 return &TruncateError{errorMsg}, nil 971 case primitive.ErrorCodeSyntaxError: 972 return &SyntaxError{errorMsg}, nil 973 case primitive.ErrorCodeUnauthorized: 974 return &Unauthorized{errorMsg}, nil 975 case primitive.ErrorCodeInvalid: 976 return &Invalid{errorMsg}, nil 977 case primitive.ErrorCodeConfigError: 978 return &ConfigError{errorMsg}, nil 979 980 case primitive.ErrorCodeUnavailable: 981 var msg = &Unavailable{ErrorMessage: errorMsg} 982 var consistency uint16 983 if consistency, err = primitive.ReadShort(source); err != nil { 984 return nil, fmt.Errorf("cannot read ERROR UNAVAILABLE consistency: %w", err) 985 } 986 msg.Consistency = primitive.ConsistencyLevel(consistency) 987 if msg.Required, err = primitive.ReadInt(source); err != nil { 988 return nil, fmt.Errorf("cannot read ERROR UNAVAILABLE required: %w", err) 989 } 990 if msg.Alive, err = primitive.ReadInt(source); err != nil { 991 return nil, fmt.Errorf("cannot read ERROR UNAVAILABLE alive: %w", err) 992 } 993 return msg, nil 994 995 case primitive.ErrorCodeReadTimeout: 996 var msg = &ReadTimeout{ErrorMessage: errorMsg} 997 var consistency uint16 998 if consistency, err = primitive.ReadShort(source); err != nil { 999 return nil, fmt.Errorf("cannot read ERROR READ TIMEOUT consistency: %w", err) 1000 } 1001 msg.Consistency = primitive.ConsistencyLevel(consistency) 1002 if msg.Received, err = primitive.ReadInt(source); err != nil { 1003 return nil, fmt.Errorf("cannot read ERROR READ TIMEOUT received: %w", err) 1004 } 1005 if msg.BlockFor, err = primitive.ReadInt(source); err != nil { 1006 return nil, fmt.Errorf("cannot read ERROR READ TIMEOUT block for: %w", err) 1007 } 1008 var b byte 1009 if b, err = primitive.ReadByte(source); err != nil { 1010 return nil, fmt.Errorf("cannot read ERROR READ TIMEOUT data present: %w", err) 1011 } 1012 if b > 0 { 1013 msg.DataPresent = true 1014 } else { 1015 msg.DataPresent = false 1016 } 1017 return msg, nil 1018 1019 case primitive.ErrorCodeWriteTimeout: 1020 var msg = &WriteTimeout{ErrorMessage: errorMsg} 1021 var consistency uint16 1022 if consistency, err = primitive.ReadShort(source); err != nil { 1023 return nil, fmt.Errorf("cannot read ERROR WRITE TIMEOUT consistency: %w", err) 1024 } 1025 msg.Consistency = primitive.ConsistencyLevel(consistency) 1026 if msg.Received, err = primitive.ReadInt(source); err != nil { 1027 return nil, fmt.Errorf("cannot read ERROR WRITE TIMEOUT received: %w", err) 1028 } 1029 if msg.BlockFor, err = primitive.ReadInt(source); err != nil { 1030 return nil, fmt.Errorf("cannot read ERROR WRITE TIMEOUT block for: %w", err) 1031 } 1032 var writeType string 1033 if writeType, err = primitive.ReadString(source); err != nil { 1034 return nil, fmt.Errorf("cannot read ERROR WRITE TIMEOUT write type: %w", err) 1035 } 1036 msg.WriteType = primitive.WriteType(writeType) 1037 if msg.WriteType == primitive.WriteTypeCas && version.SupportsWriteTimeoutContentions() { 1038 var contentions uint16 1039 if contentions, err = primitive.ReadShort(source); err != nil { 1040 return nil, fmt.Errorf("cannot read ERROR WRITE TIMEOUT contentions: %w", err) 1041 } 1042 msg.Contentions = contentions 1043 } 1044 return msg, nil 1045 1046 case primitive.ErrorCodeReadFailure: 1047 var msg = &ReadFailure{ErrorMessage: errorMsg} 1048 var consistency uint16 1049 if consistency, err = primitive.ReadShort(source); err != nil { 1050 return nil, fmt.Errorf("cannot read ERROR READ FAILURE consistency: %w", err) 1051 } 1052 msg.Consistency = primitive.ConsistencyLevel(consistency) 1053 if msg.Received, err = primitive.ReadInt(source); err != nil { 1054 return nil, fmt.Errorf("cannot read ERROR READ FAILURE received: %w", err) 1055 } 1056 if msg.BlockFor, err = primitive.ReadInt(source); err != nil { 1057 return nil, fmt.Errorf("cannot read ERROR READ FAILURE block for: %w", err) 1058 } 1059 if version.SupportsReadWriteFailureReasonMap() { 1060 if msg.FailureReasons, err = primitive.ReadReasonMap(source); err != nil { 1061 return nil, fmt.Errorf("cannot read ERROR READ FAILURE reason map: %w", err) 1062 } 1063 } else { 1064 if msg.NumFailures, err = primitive.ReadInt(source); err != nil { 1065 return nil, fmt.Errorf("cannot read ERROR READ FAILURE num failures: %w", err) 1066 } 1067 } 1068 var b byte 1069 if b, err = primitive.ReadByte(source); err != nil { 1070 return nil, fmt.Errorf("cannot read ERROR READ FAILURE data present: %w", err) 1071 } 1072 if b > 0 { 1073 msg.DataPresent = true 1074 } else { 1075 msg.DataPresent = false 1076 } 1077 return msg, nil 1078 1079 case primitive.ErrorCodeWriteFailure: 1080 var msg = &WriteFailure{ErrorMessage: errorMsg} 1081 var consistency uint16 1082 if consistency, err = primitive.ReadShort(source); err != nil { 1083 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE consistency: %w", err) 1084 } 1085 msg.Consistency = primitive.ConsistencyLevel(consistency) 1086 if msg.Received, err = primitive.ReadInt(source); err != nil { 1087 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE received: %w", err) 1088 } 1089 if msg.BlockFor, err = primitive.ReadInt(source); err != nil { 1090 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE block for: %w", err) 1091 } 1092 if version.SupportsReadWriteFailureReasonMap() { 1093 if msg.FailureReasons, err = primitive.ReadReasonMap(source); err != nil { 1094 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE reason map: %w", err) 1095 } 1096 } else { 1097 if msg.NumFailures, err = primitive.ReadInt(source); err != nil { 1098 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE num failures: %w", err) 1099 } 1100 } 1101 var writeType string 1102 if writeType, err = primitive.ReadString(source); err != nil { 1103 return nil, fmt.Errorf("cannot read ERROR WRITE FAILURE write type: %w", err) 1104 } 1105 msg.WriteType = primitive.WriteType(writeType) 1106 if err = primitive.CheckValidWriteType(msg.WriteType); err != nil { 1107 return nil, err 1108 } 1109 return msg, nil 1110 1111 case primitive.ErrorCodeFunctionFailure: 1112 var msg = &FunctionFailure{ErrorMessage: errorMsg} 1113 if msg.Keyspace, err = primitive.ReadString(source); err != nil { 1114 return nil, fmt.Errorf("cannot read ERROR FUNCTION FAILURE keyspace: %w", err) 1115 } 1116 if msg.Function, err = primitive.ReadString(source); err != nil { 1117 return nil, fmt.Errorf("cannot read ERROR FUNCTION FAILURE function: %w", err) 1118 } 1119 if msg.Arguments, err = primitive.ReadStringList(source); err != nil { 1120 return nil, fmt.Errorf("cannot read ERROR FUNCTION FAILURE arguments: %w", err) 1121 } 1122 return msg, nil 1123 1124 case primitive.ErrorCodeAlreadyExists: 1125 var msg = &AlreadyExists{ErrorMessage: errorMsg} 1126 if msg.Keyspace, err = primitive.ReadString(source); err != nil { 1127 return nil, fmt.Errorf("cannot read ERROR ALREADY EXISTS keyspace: %w", err) 1128 } 1129 if msg.Table, err = primitive.ReadString(source); err != nil { 1130 return nil, fmt.Errorf("cannot read ERROR ALREADY EXISTS table: %w", err) 1131 } 1132 return msg, nil 1133 1134 case primitive.ErrorCodeUnprepared: 1135 var msg = &Unprepared{ErrorMessage: errorMsg} 1136 if msg.Id, err = primitive.ReadShortBytes(source); err != nil { 1137 return nil, fmt.Errorf("cannot read ERROR UNPREPARED id: %w", err) 1138 } 1139 return msg, nil 1140 1141 default: 1142 err = fmt.Errorf("unknown ERROR code: %v", code) 1143 1144 } 1145 return msg, err 1146 } 1147 1148 func (c *errorCodec) GetOpCode() primitive.OpCode { 1149 return primitive.OpCodeError 1150 }