github.com/hoveychen/kafka-go@v0.4.42/error.go (about) 1 package kafka 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "syscall" 8 ) 9 10 // Error represents the different error codes that may be returned by kafka. 11 // https://kafka.apache.org/protocol#protocol_error_codes 12 type Error int 13 14 const ( 15 Unknown Error = -1 16 OffsetOutOfRange Error = 1 17 InvalidMessage Error = 2 18 UnknownTopicOrPartition Error = 3 19 InvalidMessageSize Error = 4 20 LeaderNotAvailable Error = 5 21 NotLeaderForPartition Error = 6 22 RequestTimedOut Error = 7 23 BrokerNotAvailable Error = 8 24 ReplicaNotAvailable Error = 9 25 MessageSizeTooLarge Error = 10 26 StaleControllerEpoch Error = 11 27 OffsetMetadataTooLarge Error = 12 28 NetworkException Error = 13 29 GroupLoadInProgress Error = 14 30 GroupCoordinatorNotAvailable Error = 15 31 NotCoordinatorForGroup Error = 16 32 InvalidTopic Error = 17 33 RecordListTooLarge Error = 18 34 NotEnoughReplicas Error = 19 35 NotEnoughReplicasAfterAppend Error = 20 36 InvalidRequiredAcks Error = 21 37 IllegalGeneration Error = 22 38 InconsistentGroupProtocol Error = 23 39 InvalidGroupId Error = 24 40 UnknownMemberId Error = 25 41 InvalidSessionTimeout Error = 26 42 RebalanceInProgress Error = 27 43 InvalidCommitOffsetSize Error = 28 44 TopicAuthorizationFailed Error = 29 45 GroupAuthorizationFailed Error = 30 46 ClusterAuthorizationFailed Error = 31 47 InvalidTimestamp Error = 32 48 UnsupportedSASLMechanism Error = 33 49 IllegalSASLState Error = 34 50 UnsupportedVersion Error = 35 51 TopicAlreadyExists Error = 36 52 InvalidPartitionNumber Error = 37 53 InvalidReplicationFactor Error = 38 54 InvalidReplicaAssignment Error = 39 55 InvalidConfiguration Error = 40 56 NotController Error = 41 57 InvalidRequest Error = 42 58 UnsupportedForMessageFormat Error = 43 59 PolicyViolation Error = 44 60 OutOfOrderSequenceNumber Error = 45 61 DuplicateSequenceNumber Error = 46 62 InvalidProducerEpoch Error = 47 63 InvalidTransactionState Error = 48 64 InvalidProducerIDMapping Error = 49 65 InvalidTransactionTimeout Error = 50 66 ConcurrentTransactions Error = 51 67 TransactionCoordinatorFenced Error = 52 68 TransactionalIDAuthorizationFailed Error = 53 69 SecurityDisabled Error = 54 70 BrokerAuthorizationFailed Error = 55 71 KafkaStorageError Error = 56 72 LogDirNotFound Error = 57 73 SASLAuthenticationFailed Error = 58 74 UnknownProducerId Error = 59 75 ReassignmentInProgress Error = 60 76 DelegationTokenAuthDisabled Error = 61 77 DelegationTokenNotFound Error = 62 78 DelegationTokenOwnerMismatch Error = 63 79 DelegationTokenRequestNotAllowed Error = 64 80 DelegationTokenAuthorizationFailed Error = 65 81 DelegationTokenExpired Error = 66 82 InvalidPrincipalType Error = 67 83 NonEmptyGroup Error = 68 84 GroupIdNotFound Error = 69 85 FetchSessionIDNotFound Error = 70 86 InvalidFetchSessionEpoch Error = 71 87 ListenerNotFound Error = 72 88 TopicDeletionDisabled Error = 73 89 FencedLeaderEpoch Error = 74 90 UnknownLeaderEpoch Error = 75 91 UnsupportedCompressionType Error = 76 92 StaleBrokerEpoch Error = 77 93 OffsetNotAvailable Error = 78 94 MemberIDRequired Error = 79 95 PreferredLeaderNotAvailable Error = 80 96 GroupMaxSizeReached Error = 81 97 FencedInstanceID Error = 82 98 EligibleLeadersNotAvailable Error = 83 99 ElectionNotNeeded Error = 84 100 NoReassignmentInProgress Error = 85 101 GroupSubscribedToTopic Error = 86 102 InvalidRecord Error = 87 103 UnstableOffsetCommit Error = 88 104 ThrottlingQuotaExceeded Error = 89 105 ProducerFenced Error = 90 106 ResourceNotFound Error = 91 107 DuplicateResource Error = 92 108 UnacceptableCredential Error = 93 109 InconsistentVoterSet Error = 94 110 InvalidUpdateVersion Error = 95 111 FeatureUpdateFailed Error = 96 112 PrincipalDeserializationFailure Error = 97 113 SnapshotNotFound Error = 98 114 PositionOutOfRange Error = 99 115 UnknownTopicID Error = 100 116 DuplicateBrokerRegistration Error = 101 117 BrokerIDNotRegistered Error = 102 118 InconsistentTopicID Error = 103 119 InconsistentClusterID Error = 104 120 TransactionalIDNotFound Error = 105 121 FetchSessionTopicIDError Error = 106 122 ) 123 124 // Error satisfies the error interface. 125 func (e Error) Error() string { 126 return fmt.Sprintf("[%d] %s: %s", e, e.Title(), e.Description()) 127 } 128 129 // Timeout returns true if the error was due to a timeout. 130 func (e Error) Timeout() bool { 131 return e == RequestTimedOut 132 } 133 134 // Temporary returns true if the operation that generated the error may succeed 135 // if retried at a later time. 136 // Kafka error documentation specifies these as "retriable" 137 // https://kafka.apache.org/protocol#protocol_error_codes 138 func (e Error) Temporary() bool { 139 switch e { 140 case InvalidMessage, 141 UnknownTopicOrPartition, 142 LeaderNotAvailable, 143 NotLeaderForPartition, 144 RequestTimedOut, 145 NetworkException, 146 GroupLoadInProgress, 147 GroupCoordinatorNotAvailable, 148 NotCoordinatorForGroup, 149 NotEnoughReplicas, 150 NotEnoughReplicasAfterAppend, 151 NotController, 152 KafkaStorageError, 153 FetchSessionIDNotFound, 154 InvalidFetchSessionEpoch, 155 ListenerNotFound, 156 FencedLeaderEpoch, 157 UnknownLeaderEpoch, 158 OffsetNotAvailable, 159 PreferredLeaderNotAvailable, 160 EligibleLeadersNotAvailable, 161 ElectionNotNeeded, 162 NoReassignmentInProgress, 163 GroupSubscribedToTopic, 164 UnstableOffsetCommit, 165 ThrottlingQuotaExceeded, 166 UnknownTopicID, 167 InconsistentTopicID, 168 FetchSessionTopicIDError: 169 return true 170 default: 171 return false 172 } 173 } 174 175 // Title returns a human readable title for the error. 176 func (e Error) Title() string { 177 switch e { 178 case Unknown: 179 return "Unknown" 180 case OffsetOutOfRange: 181 return "Offset Out Of Range" 182 case InvalidMessage: 183 return "Invalid Message" 184 case UnknownTopicOrPartition: 185 return "Unknown Topic Or Partition" 186 case InvalidMessageSize: 187 return "Invalid Message Size" 188 case LeaderNotAvailable: 189 return "Leader Not Available" 190 case NotLeaderForPartition: 191 return "Not Leader For Partition" 192 case RequestTimedOut: 193 return "Request Timed Out" 194 case BrokerNotAvailable: 195 return "Broker Not Available" 196 case ReplicaNotAvailable: 197 return "Replica Not Available" 198 case MessageSizeTooLarge: 199 return "Message Size Too Large" 200 case StaleControllerEpoch: 201 return "Stale Controller Epoch" 202 case OffsetMetadataTooLarge: 203 return "Offset Metadata Too Large" 204 case GroupLoadInProgress: 205 return "Group Load In Progress" 206 case GroupCoordinatorNotAvailable: 207 return "Group Coordinator Not Available" 208 case NotCoordinatorForGroup: 209 return "Not Coordinator For Group" 210 case InvalidTopic: 211 return "Invalid Topic" 212 case RecordListTooLarge: 213 return "Record List Too Large" 214 case NotEnoughReplicas: 215 return "Not Enough Replicas" 216 case NotEnoughReplicasAfterAppend: 217 return "Not Enough Replicas After Append" 218 case InvalidRequiredAcks: 219 return "Invalid Required Acks" 220 case IllegalGeneration: 221 return "Illegal Generation" 222 case InconsistentGroupProtocol: 223 return "Inconsistent Group Protocol" 224 case InvalidGroupId: 225 return "Invalid Group ID" 226 case UnknownMemberId: 227 return "Unknown Member ID" 228 case InvalidSessionTimeout: 229 return "Invalid Session Timeout" 230 case RebalanceInProgress: 231 return "Rebalance In Progress" 232 case InvalidCommitOffsetSize: 233 return "Invalid Commit Offset Size" 234 case TopicAuthorizationFailed: 235 return "Topic Authorization Failed" 236 case GroupAuthorizationFailed: 237 return "Group Authorization Failed" 238 case ClusterAuthorizationFailed: 239 return "Cluster Authorization Failed" 240 case InvalidTimestamp: 241 return "Invalid Timestamp" 242 case UnsupportedSASLMechanism: 243 return "Unsupported SASL Mechanism" 244 case IllegalSASLState: 245 return "Illegal SASL State" 246 case UnsupportedVersion: 247 return "Unsupported Version" 248 case TopicAlreadyExists: 249 return "Topic Already Exists" 250 case InvalidPartitionNumber: 251 return "Invalid Partition Number" 252 case InvalidReplicationFactor: 253 return "Invalid Replication Factor" 254 case InvalidReplicaAssignment: 255 return "Invalid Replica Assignment" 256 case InvalidConfiguration: 257 return "Invalid Configuration" 258 case NotController: 259 return "Not Controller" 260 case InvalidRequest: 261 return "Invalid Request" 262 case UnsupportedForMessageFormat: 263 return "Unsupported For Message Format" 264 case PolicyViolation: 265 return "Policy Violation" 266 case OutOfOrderSequenceNumber: 267 return "Out Of Order Sequence Number" 268 case DuplicateSequenceNumber: 269 return "Duplicate Sequence Number" 270 case InvalidProducerEpoch: 271 return "Invalid Producer Epoch" 272 case InvalidTransactionState: 273 return "Invalid Transaction State" 274 case InvalidProducerIDMapping: 275 return "Invalid Producer ID Mapping" 276 case InvalidTransactionTimeout: 277 return "Invalid Transaction Timeout" 278 case ConcurrentTransactions: 279 return "Concurrent Transactions" 280 case TransactionCoordinatorFenced: 281 return "Transaction Coordinator Fenced" 282 case TransactionalIDAuthorizationFailed: 283 return "Transactional ID Authorization Failed" 284 case SecurityDisabled: 285 return "Security Disabled" 286 case BrokerAuthorizationFailed: 287 return "Broker Authorization Failed" 288 case KafkaStorageError: 289 return "Kafka Storage Error" 290 case LogDirNotFound: 291 return "Log Dir Not Found" 292 case SASLAuthenticationFailed: 293 return "SASL Authentication Failed" 294 case UnknownProducerId: 295 return "Unknown Producer ID" 296 case ReassignmentInProgress: 297 return "Reassignment In Progress" 298 case DelegationTokenAuthDisabled: 299 return "Delegation Token Auth Disabled" 300 case DelegationTokenNotFound: 301 return "Delegation Token Not Found" 302 case DelegationTokenOwnerMismatch: 303 return "Delegation Token Owner Mismatch" 304 case DelegationTokenRequestNotAllowed: 305 return "Delegation Token Request Not Allowed" 306 case DelegationTokenAuthorizationFailed: 307 return "Delegation Token Authorization Failed" 308 case DelegationTokenExpired: 309 return "Delegation Token Expired" 310 case InvalidPrincipalType: 311 return "Invalid Principal Type" 312 case NonEmptyGroup: 313 return "Non Empty Group" 314 case GroupIdNotFound: 315 return "Group ID Not Found" 316 case FetchSessionIDNotFound: 317 return "Fetch Session ID Not Found" 318 case InvalidFetchSessionEpoch: 319 return "Invalid Fetch Session Epoch" 320 case ListenerNotFound: 321 return "Listener Not Found" 322 case TopicDeletionDisabled: 323 return "Topic Deletion Disabled" 324 case FencedLeaderEpoch: 325 return "Fenced Leader Epoch" 326 case UnknownLeaderEpoch: 327 return "Unknown Leader Epoch" 328 case UnsupportedCompressionType: 329 return "Unsupported Compression Type" 330 case MemberIDRequired: 331 return "Member ID Required" 332 case EligibleLeadersNotAvailable: 333 return "Eligible Leader Not Available" 334 case ElectionNotNeeded: 335 return "Election Not Needed" 336 case NoReassignmentInProgress: 337 return "No Reassignment In Progress" 338 case GroupSubscribedToTopic: 339 return "Group Subscribed To Topic" 340 case InvalidRecord: 341 return "Invalid Record" 342 case UnstableOffsetCommit: 343 return "Unstable Offset Commit" 344 case ThrottlingQuotaExceeded: 345 return "Throttling Quota Exceeded" 346 case ProducerFenced: 347 return "Producer Fenced" 348 case ResourceNotFound: 349 return "Resource Not Found" 350 case DuplicateResource: 351 return "Duplicate Resource" 352 case UnacceptableCredential: 353 return "Unacceptable Credential" 354 case InconsistentVoterSet: 355 return "Inconsistent Voter Set" 356 case InvalidUpdateVersion: 357 return "Invalid Update Version" 358 case FeatureUpdateFailed: 359 return "Feature Update Failed" 360 case PrincipalDeserializationFailure: 361 return "Principal Deserialization Failure" 362 case SnapshotNotFound: 363 return "Snapshot Not Found" 364 case PositionOutOfRange: 365 return "Position Out Of Range" 366 case UnknownTopicID: 367 return "Unknown Topic ID" 368 case DuplicateBrokerRegistration: 369 return "Duplicate Broker Registration" 370 case BrokerIDNotRegistered: 371 return "Broker ID Not Registered" 372 case InconsistentTopicID: 373 return "Inconsistent Topic ID" 374 case InconsistentClusterID: 375 return "Inconsistent Cluster ID" 376 case TransactionalIDNotFound: 377 return "Transactional ID Not Found" 378 case FetchSessionTopicIDError: 379 return "Fetch Session Topic ID Error" 380 } 381 return "" 382 } 383 384 // Description returns a human readable description of cause of the error. 385 func (e Error) Description() string { 386 switch e { 387 case Unknown: 388 return "an unexpected server error occurred" 389 case OffsetOutOfRange: 390 return "the requested offset is outside the range of offsets maintained by the server for the given topic/partition" 391 case InvalidMessage: 392 return "the message contents does not match its CRC" 393 case UnknownTopicOrPartition: 394 return "the request is for a topic or partition that does not exist on this broker" 395 case InvalidMessageSize: 396 return "the message has a negative size" 397 case LeaderNotAvailable: 398 return "the cluster is in the middle of a leadership election and there is currently no leader for this partition and hence it is unavailable for writes" 399 case NotLeaderForPartition: 400 return "the client attempted to send messages to a replica that is not the leader for some partition, the client's metadata are likely out of date" 401 case RequestTimedOut: 402 return "the request exceeded the user-specified time limit in the request" 403 case BrokerNotAvailable: 404 return "not a client facing error and is used mostly by tools when a broker is not alive" 405 case ReplicaNotAvailable: 406 return "a replica is expected on a broker, but is not (this can be safely ignored)" 407 case MessageSizeTooLarge: 408 return "the server has a configurable maximum message size to avoid unbounded memory allocation and the client attempted to produce a message larger than this maximum" 409 case StaleControllerEpoch: 410 return "internal error code for broker-to-broker communication" 411 case OffsetMetadataTooLarge: 412 return "the client specified a string larger than configured maximum for offset metadata" 413 case GroupLoadInProgress: 414 return "the broker returns this error code for an offset fetch request if it is still loading offsets (after a leader change for that offsets topic partition), or in response to group membership requests (such as heartbeats) when group metadata is being loaded by the coordinator" 415 case GroupCoordinatorNotAvailable: 416 return "the broker returns this error code for group coordinator requests, offset commits, and most group management requests if the offsets topic has not yet been created, or if the group coordinator is not active" 417 case NotCoordinatorForGroup: 418 return "the broker returns this error code if it receives an offset fetch or commit request for a group that it is not a coordinator for" 419 case InvalidTopic: 420 return "a request which attempted to access an invalid topic (e.g. one which has an illegal name), or if an attempt was made to write to an internal topic (such as the consumer offsets topic)" 421 case RecordListTooLarge: 422 return "a message batch in a produce request exceeds the maximum configured segment size" 423 case NotEnoughReplicas: 424 return "the number of in-sync replicas is lower than the configured minimum and requiredAcks is -1" 425 case NotEnoughReplicasAfterAppend: 426 return "the message was written to the log, but with fewer in-sync replicas than required." 427 case InvalidRequiredAcks: 428 return "the requested requiredAcks is invalid (anything other than -1, 1, or 0)" 429 case IllegalGeneration: 430 return "the generation id provided in the request is not the current generation" 431 case InconsistentGroupProtocol: 432 return "the member provided a protocol type or set of protocols which is not compatible with the current group" 433 case InvalidGroupId: 434 return "the group id is empty or null" 435 case UnknownMemberId: 436 return "the member id is not in the current generation" 437 case InvalidSessionTimeout: 438 return "the requested session timeout is outside of the allowed range on the broker" 439 case RebalanceInProgress: 440 return "the coordinator has begun rebalancing the group, the client should rejoin the group" 441 case InvalidCommitOffsetSize: 442 return "an offset commit was rejected because of oversize metadata" 443 case TopicAuthorizationFailed: 444 return "the client is not authorized to access the requested topic" 445 case GroupAuthorizationFailed: 446 return "the client is not authorized to access a particular group id" 447 case ClusterAuthorizationFailed: 448 return "the client is not authorized to use an inter-broker or administrative API" 449 case InvalidTimestamp: 450 return "the timestamp of the message is out of acceptable range" 451 case UnsupportedSASLMechanism: 452 return "the broker does not support the requested SASL mechanism" 453 case IllegalSASLState: 454 return "the request is not valid given the current SASL state" 455 case UnsupportedVersion: 456 return "the version of API is not supported" 457 case TopicAlreadyExists: 458 return "a topic with this name already exists" 459 case InvalidPartitionNumber: 460 return "the number of partitions is invalid" 461 case InvalidReplicationFactor: 462 return "the replication-factor is invalid" 463 case InvalidReplicaAssignment: 464 return "the replica assignment is invalid" 465 case InvalidConfiguration: 466 return "the configuration is invalid" 467 case NotController: 468 return "this is not the correct controller for this cluster" 469 case InvalidRequest: 470 return "this most likely occurs because of a request being malformed by the client library or the message was sent to an incompatible broker, se the broker logs for more details" 471 case UnsupportedForMessageFormat: 472 return "the message format version on the broker does not support the request" 473 case PolicyViolation: 474 return "the request parameters do not satisfy the configured policy" 475 case OutOfOrderSequenceNumber: 476 return "the broker received an out of order sequence number" 477 case DuplicateSequenceNumber: 478 return "the broker received a duplicate sequence number" 479 case InvalidProducerEpoch: 480 return "the producer attempted an operation with an old epoch, either there is a newer producer with the same transactional ID, or the producer's transaction has been expired by the broker" 481 case InvalidTransactionState: 482 return "the producer attempted a transactional operation in an invalid state" 483 case InvalidProducerIDMapping: 484 return "the producer attempted to use a producer id which is not currently assigned to its transactional ID" 485 case InvalidTransactionTimeout: 486 return "the transaction timeout is larger than the maximum value allowed by the broker (as configured by max.transaction.timeout.ms)" 487 case ConcurrentTransactions: 488 return "the producer attempted to update a transaction while another concurrent operation on the same transaction was ongoing" 489 case TransactionCoordinatorFenced: 490 return "the transaction coordinator sending a WriteTxnMarker is no longer the current coordinator for a given producer" 491 case TransactionalIDAuthorizationFailed: 492 return "the transactional ID authorization failed" 493 case SecurityDisabled: 494 return "the security features are disabled" 495 case BrokerAuthorizationFailed: 496 return "the broker authorization failed" 497 case KafkaStorageError: 498 return "disk error when trying to access log file on the disk" 499 case LogDirNotFound: 500 return "the user-specified log directory is not found in the broker config" 501 case SASLAuthenticationFailed: 502 return "SASL Authentication failed" 503 case UnknownProducerId: 504 return "the broker could not locate the producer metadata associated with the producer ID" 505 case ReassignmentInProgress: 506 return "a partition reassignment is in progress" 507 case DelegationTokenAuthDisabled: 508 return "delegation token feature is not enabled" 509 case DelegationTokenNotFound: 510 return "delegation token is not found on server" 511 case DelegationTokenOwnerMismatch: 512 return "specified principal is not valid owner/renewer" 513 case DelegationTokenRequestNotAllowed: 514 return "delegation token requests are not allowed on plaintext/1-way ssl channels and on delegation token authenticated channels" 515 case DelegationTokenAuthorizationFailed: 516 return "delegation token authorization failed" 517 case DelegationTokenExpired: 518 return "delegation token is expired" 519 case InvalidPrincipalType: 520 return "supplied principaltype is not supported" 521 case NonEmptyGroup: 522 return "the group is not empty" 523 case GroupIdNotFound: 524 return "the group ID does not exist" 525 case FetchSessionIDNotFound: 526 return "the fetch session ID was not found" 527 case InvalidFetchSessionEpoch: 528 return "the fetch session epoch is invalid" 529 case ListenerNotFound: 530 return "there is no listener on the leader broker that matches the listener on which metadata request was processed" 531 case TopicDeletionDisabled: 532 return "topic deletion is disabled" 533 case FencedLeaderEpoch: 534 return "the leader epoch in the request is older than the epoch on the broker" 535 case UnknownLeaderEpoch: 536 return "the leader epoch in the request is newer than the epoch on the broker" 537 case UnsupportedCompressionType: 538 return "the requesting client does not support the compression type of given partition" 539 case MemberIDRequired: 540 return "the group member needs to have a valid member id before actually entering a consumer group" 541 case EligibleLeadersNotAvailable: 542 return "eligible topic partition leaders are not available" 543 case ElectionNotNeeded: 544 return "leader election not needed for topic partition" 545 case NoReassignmentInProgress: 546 return "no partition reassignment is in progress" 547 case GroupSubscribedToTopic: 548 return "deleting offsets of a topic is forbidden while the consumer group is actively subscribed to it" 549 case InvalidRecord: 550 return "this record has failed the validation on broker and hence be rejected" 551 case UnstableOffsetCommit: 552 return "there are unstable offsets that need to be cleared" 553 case ThrottlingQuotaExceeded: 554 return "The throttling quota has been exceeded" 555 case ProducerFenced: 556 return "There is a newer producer with the same transactionalId which fences the current one" 557 case ResourceNotFound: 558 return "A request illegally referred to a resource that does not exist" 559 case DuplicateResource: 560 return "A request illegally referred to the same resource twice" 561 case UnacceptableCredential: 562 return "Requested credential would not meet criteria for acceptability" 563 case InconsistentVoterSet: 564 return "Indicates that the either the sender or recipient of a voter-only request is not one of the expected voters" 565 case InvalidUpdateVersion: 566 return "The given update version was invalid" 567 case FeatureUpdateFailed: 568 return "Unable to update finalized features due to an unexpected server error" 569 case PrincipalDeserializationFailure: 570 return "Request principal deserialization failed during forwarding. This indicates an internal error on the broker cluster security setup" 571 case SnapshotNotFound: 572 return "Requested snapshot was not found" 573 case PositionOutOfRange: 574 return "Requested position is not greater than or equal to zero, and less than the size of the snapshot" 575 case UnknownTopicID: 576 return "This server does not host this topic ID" 577 case DuplicateBrokerRegistration: 578 return "This broker ID is already in use" 579 case BrokerIDNotRegistered: 580 return "The given broker ID was not registered" 581 case InconsistentTopicID: 582 return "The log's topic ID did not match the topic ID in the request" 583 case InconsistentClusterID: 584 return "The clusterId in the request does not match that found on the server" 585 case TransactionalIDNotFound: 586 return "The transactionalId could not be found" 587 case FetchSessionTopicIDError: 588 return "The fetch session encountered inconsistent topic ID usage" 589 } 590 return "" 591 } 592 593 func isTimeout(err error) bool { 594 var timeoutError interface{ Timeout() bool } 595 if errors.As(err, &timeoutError) { 596 return timeoutError.Timeout() 597 } 598 return false 599 } 600 601 func isTemporary(err error) bool { 602 var tempError interface{ Temporary() bool } 603 if errors.As(err, &tempError) { 604 return tempError.Temporary() 605 } 606 return false 607 } 608 609 func isTransientNetworkError(err error) bool { 610 return errors.Is(err, io.ErrUnexpectedEOF) || 611 errors.Is(err, syscall.ECONNREFUSED) || 612 errors.Is(err, syscall.ECONNRESET) || 613 errors.Is(err, syscall.EPIPE) 614 } 615 616 func silentEOF(err error) error { 617 if errors.Is(err, io.EOF) { 618 err = nil 619 } 620 return err 621 } 622 623 func dontExpectEOF(err error) error { 624 if errors.Is(err, io.EOF) { 625 return io.ErrUnexpectedEOF 626 } 627 return err 628 } 629 630 func coalesceErrors(errs ...error) error { 631 for _, err := range errs { 632 if err != nil { 633 return err 634 } 635 } 636 return nil 637 } 638 639 type MessageTooLargeError struct { 640 Message Message 641 Remaining []Message 642 } 643 644 func messageTooLarge(msgs []Message, i int) MessageTooLargeError { 645 remain := make([]Message, 0, len(msgs)-1) 646 remain = append(remain, msgs[:i]...) 647 remain = append(remain, msgs[i+1:]...) 648 return MessageTooLargeError{ 649 Message: msgs[i], 650 Remaining: remain, 651 } 652 } 653 654 func (e MessageTooLargeError) Error() string { 655 return MessageSizeTooLarge.Error() 656 } 657 658 func makeError(code int16, message string) error { 659 if code == 0 { 660 return nil 661 } 662 if message == "" { 663 return Error(code) 664 } 665 return fmt.Errorf("%w: %s", Error(code), message) 666 } 667 668 // WriteError is returned by kafka.(*Writer).WriteMessages when the writer is 669 // not configured to write messages asynchronously. WriteError values contain 670 // a list of errors where each entry matches the position of a message in the 671 // WriteMessages call. The program can determine the status of each message by 672 // looping over the error: 673 // 674 // switch err := w.WriteMessages(ctx, msgs...).(type) { 675 // case nil: 676 // case kafka.WriteErrors: 677 // for i := range msgs { 678 // if err[i] != nil { 679 // // handle the error writing msgs[i] 680 // ... 681 // } 682 // } 683 // default: 684 // // handle other errors 685 // ... 686 // } 687 type WriteErrors []error 688 689 // Count counts the number of non-nil errors in err. 690 func (err WriteErrors) Count() int { 691 n := 0 692 693 for _, e := range err { 694 if e != nil { 695 n++ 696 } 697 } 698 699 return n 700 } 701 702 func (err WriteErrors) Error() string { 703 errCount := err.Count() 704 errors := make([]string, 0, errCount) 705 for _, writeError := range err { 706 if writeError == nil { 707 continue 708 } 709 errors = append(errors, writeError.Error()) 710 } 711 return fmt.Sprintf("Kafka write errors (%d/%d), errors: %v", errCount, len(err), errors) 712 }