feat: improve `RouterClient` errors

pull/24376/head
Marco Neumann 2021-11-15 11:18:46 +01:00
parent 5a237e2bc6
commit 48d0388ea0
2 changed files with 80 additions and 6 deletions

View File

@ -1,4 +1,8 @@
use influxdb_iox_client::router::generated_types::{QuerySinks, Router};
use influxdb_iox_client::router::{
generated_types::{Matcher, MatcherToShard, QuerySinks, Router, ShardConfig},
UpdateRouterError,
};
use test_helpers::assert_error;
use crate::{
common::server_fixture::{ServerFixture, ServerType},
@ -7,7 +11,7 @@ use crate::{
#[tokio::test]
async fn test_router_crud() {
let server_fixture = ServerFixture::create_shared(ServerType::Router).await;
let server_fixture = ServerFixture::create_single_use(ServerType::Router).await;
let mut client = server_fixture.router_client();
let router_name_a = rand_name();
@ -65,3 +69,44 @@ async fn test_router_crud() {
assert_eq!(&routers[0], &cfg_bar);
client.delete_router(&router_name_b).await.unwrap();
}
#[tokio::test]
async fn test_router_update_invalid_argument() {
let server_fixture = ServerFixture::create_single_use(ServerType::Router).await;
let mut client = server_fixture.router_client();
let router_name = rand_name();
let cfg_valid = Router {
name: router_name.clone(),
write_sharder: Default::default(),
write_sinks: Default::default(),
query_sinks: Default::default(),
};
let cfg_invalid = Router {
write_sharder: Some(ShardConfig {
specific_targets: vec![MatcherToShard {
matcher: Some(Matcher {
table_name_regex: "*".to_owned(),
}),
shard: 1,
}],
hash_ring: None,
}),
..cfg_valid.clone()
};
// invalid args don't create routers
let res = client.update_router(cfg_invalid.clone()).await;
assert_error!(res, UpdateRouterError::InvalidArgument(_));
let routers = client.list_routers().await.unwrap();
assert_eq!(routers.len(), 0);
// invalid args don't update routesr
client.update_router(cfg_valid.clone()).await.unwrap();
let res = client.update_router(cfg_invalid).await;
assert_error!(res, UpdateRouterError::InvalidArgument(_));
let routers = client.list_routers().await.unwrap();
assert_eq!(routers.len(), 1);
assert_eq!(&routers[0], &cfg_valid);
}

View File

@ -13,6 +13,10 @@ pub mod generated_types {
/// Errors returned by Client::list_routers
#[derive(Debug, Error)]
pub enum ListRoutersError {
/// Server indicated that it is not (yet) available
#[error("Server unavailable: {}", .0.message())]
Unavailable(tonic::Status),
/// Client received an unexpected error from the server
#[error("Unexpected server error: {}: {}", .0.code(), .0.message())]
ServerError(tonic::Status),
@ -21,6 +25,14 @@ pub enum ListRoutersError {
/// Errors returned by Client::update_router
#[derive(Debug, Error)]
pub enum UpdateRouterError {
/// Server indicated that it is not (yet) available
#[error("Server unavailable: {}", .0.message())]
Unavailable(tonic::Status),
/// Server returned an invalid argument error
#[error("Invalid argument: {}", .0.message())]
InvalidArgument(tonic::Status),
/// Client received an unexpected error from the server
#[error("Unexpected server error: {}: {}", .0.code(), .0.message())]
ServerError(tonic::Status),
@ -29,6 +41,10 @@ pub enum UpdateRouterError {
/// Errors returned by Client::delete_router
#[derive(Debug, Error)]
pub enum DeleteRouterError {
/// Server indicated that it is not (yet) available
#[error("Server unavailable: {}", .0.message())]
Unavailable(tonic::Status),
/// Client received an unexpected error from the server
#[error("Unexpected server error: {}: {}", .0.code(), .0.message())]
ServerError(tonic::Status),
@ -80,7 +96,11 @@ impl Client {
.inner
.list_routers(ListRoutersRequest {})
.await
.map_err(ListRoutersError::ServerError)?;
.map_err(|status| match status.code() {
tonic::Code::Unavailable => ListRoutersError::Unavailable(status),
_ => ListRoutersError::ServerError(status),
})?;
Ok(response.into_inner().routers)
}
@ -94,18 +114,27 @@ impl Client {
router: Some(config),
})
.await
.map_err(UpdateRouterError::ServerError)?;
.map_err(|status| match status.code() {
tonic::Code::Unavailable => UpdateRouterError::Unavailable(status),
tonic::Code::InvalidArgument => UpdateRouterError::InvalidArgument(status),
_ => UpdateRouterError::ServerError(status),
})?;
Ok(())
}
/// Delete router
pub async fn delete_router(&mut self, router_name: &str) -> Result<(), UpdateRouterError> {
pub async fn delete_router(&mut self, router_name: &str) -> Result<(), DeleteRouterError> {
self.inner
.delete_router(DeleteRouterRequest {
router_name: router_name.to_string(),
})
.await
.map_err(UpdateRouterError::ServerError)?;
.map_err(|status| match status.code() {
tonic::Code::Unavailable => DeleteRouterError::Unavailable(status),
_ => DeleteRouterError::ServerError(status),
})?;
Ok(())
}
}