use rdkafka::error::{KafkaError, RDKafkaErrorCode};
use spate_core::error::ErrorClass;
pub(crate) fn classify_consumer_error(code: RDKafkaErrorCode, after_startup: bool) -> ErrorClass {
use RDKafkaErrorCode as C;
match code {
C::TopicAuthorizationFailed
| C::GroupAuthorizationFailed
| C::ClusterAuthorizationFailed
| C::TransactionalIdAuthorizationFailed
| C::Authentication
| C::SaslAuthenticationFailed
| C::UnsupportedSASLMechanism
| C::IllegalSASLState
| C::SecurityDisabled
| C::InvalidTopic
| C::UnsupportedVersion
| C::UnsupportedForMessageFormat => ErrorClass::Fatal,
C::UnknownTopicOrPartition if after_startup => ErrorClass::Fatal,
_ => ErrorClass::Retryable,
}
}
pub(crate) fn classify_poll_error(err: &KafkaError, after_startup: bool) -> ErrorClass {
match err.rdkafka_error_code() {
Some(code) => classify_consumer_error(code, after_startup),
None => ErrorClass::Retryable,
}
}
#[cfg(test)]
mod tests {
use super::*;
use rdkafka::error::RDKafkaErrorCode as C;
#[test]
fn permanent_codes_classify_fatal() {
for code in [
C::TopicAuthorizationFailed,
C::GroupAuthorizationFailed,
C::ClusterAuthorizationFailed,
C::TransactionalIdAuthorizationFailed,
C::Authentication,
C::SaslAuthenticationFailed,
C::UnsupportedSASLMechanism,
C::IllegalSASLState,
C::SecurityDisabled,
C::InvalidTopic,
C::UnsupportedVersion,
C::UnsupportedForMessageFormat,
] {
assert_eq!(
classify_consumer_error(code, true),
ErrorClass::Fatal,
"{code:?} after startup"
);
assert_eq!(
classify_consumer_error(code, false),
ErrorClass::Fatal,
"{code:?} before startup"
);
}
}
#[test]
fn transient_codes_classify_retryable() {
for code in [
C::BrokerNotAvailable,
C::LeaderNotAvailable,
C::NotLeaderForPartition,
C::RequestTimedOut,
C::NetworkException,
C::CoordinatorNotAvailable,
C::CoordinatorLoadInProgress,
C::NotCoordinator,
C::RebalanceInProgress,
C::OffsetOutOfRange,
] {
assert_eq!(
classify_consumer_error(code, true),
ErrorClass::Retryable,
"{code:?}"
);
}
}
#[test]
fn unknown_topic_is_fatal_only_after_startup() {
assert_eq!(
classify_consumer_error(C::UnknownTopicOrPartition, false),
ErrorClass::Retryable,
);
assert_eq!(
classify_consumer_error(C::UnknownTopicOrPartition, true),
ErrorClass::Fatal,
);
}
}