github.com/streamdal/segmentio-kafka-go@v0.4.47-streamdal/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  }