diff --git a/tower/src/steer/mod.rs b/tower/src/steer/mod.rs index 00b3311c2..f8f7af885 100644 --- a/tower/src/steer/mod.rs +++ b/tower/src/steer/mod.rs @@ -113,9 +113,17 @@ pub struct Steer { impl Steer { /// Make a new [`Steer`] with a list of [`Service`]'s and a [`Picker`]. /// + /// # Panics + /// + /// Panics if the `services` collection is empty + /// /// Note: the order of the [`Service`]'s is significant for [`Picker::pick`]'s return value. pub fn new(services: impl IntoIterator, router: F) -> Self { let services: Vec<_> = services.into_iter().collect(); + assert!( + !services.is_empty(), + "steer must contain at least one service" + ); let not_ready: VecDeque<_> = services.iter().enumerate().map(|(i, _)| i).collect(); Self { router, diff --git a/tower/tests/steer/main.rs b/tower/tests/steer/main.rs index e3b51efe6..5702288c0 100644 --- a/tower/tests/steer/main.rs +++ b/tower/tests/steer/main.rs @@ -57,3 +57,15 @@ async fn pending_all_ready() { ), } } +#[test] +#[should_panic(expected = "steer must contain at least one service")] +fn steer_new_zero_services_panics() { + use std::iter::empty; + use tower::steer::Steer; + use tower::util::BoxService; + + let empty_services = empty::>(); + + // Explicitly annotate the Request type as () so inference succeeds + let _: Steer<_, _, ()> = Steer::new(empty_services, |_: &()| 0); +}