Skip to content

Commit

Permalink
apiclient: updated errors to match client errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sumukhballal committed Jun 7, 2024
1 parent c05d185 commit 02ee61d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
50 changes: 40 additions & 10 deletions sources/api/apiclient/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ mod error {
body: String,
},

// This type of error just returns the source.
#[snafu(display("{}", body))]
Raw { body: String },

#[snafu(display("Failed to read body of response: {}", source))]
ResponseBodyRead { source: hyper::Error },

Expand Down Expand Up @@ -85,16 +89,19 @@ where
{
let (status, body) = raw_request_unchecked(&socket_path, &uri, &method, data).await?;

// Error if the response status is in not in the 2xx range.
ensure!(
status.is_success(),
error::ResponseStatusSnafu {
method: method.as_ref(),
code: status,
uri: uri.as_ref(),
body,
}
);
// We check if there are any specific errors that are supposed to be client side validation errors.
match ClientTypeErrors::from(body.as_ref()) {
Some(_) => ensure!(status.is_success(), error::RawSnafu { body }),
None => ensure!(
status.is_success(),
error::ResponseStatusSnafu {
method: method.as_ref().to_string(),
code: status,
uri: uri.as_ref().to_string(),
body,
}
),
};

Ok((status, body))
}
Expand Down Expand Up @@ -156,6 +163,29 @@ pub(crate) fn rando() -> String {
.collect()
}

/// Different Client type errors we expect.
const CLIENT_DESERIALIZATION_MAP_ERROR: &str = "Unable to match your input to the data model. We may not have enough type information. Please try the --json input form";
const CLIENT_DESERIALIZATION_JSON_ERROR: &str = "Unable to deserialize input JSON into model";
const SERVER_DESERIALIZATION_JSON_ERROR: &str = "Json deserialize error";
const CLIENT_SERIALIZATION_ERROR: &str = "Unable to serialize data";

#[derive(Debug)]
enum ClientTypeErrors {}

impl ClientTypeErrors {
fn from(input: &str) -> Option<&str> {
if input.contains(CLIENT_DESERIALIZATION_JSON_ERROR)
|| input.contains(CLIENT_DESERIALIZATION_MAP_ERROR)
|| input.contains(SERVER_DESERIALIZATION_JSON_ERROR)
|| input.contains(CLIENT_SERIALIZATION_ERROR)
{
Some("client_error")
} else {
None
}
}
}

/// Different input types supported by the Settings API.
#[derive(Debug)]
pub enum SettingsInput {
Expand Down
21 changes: 18 additions & 3 deletions sources/api/apiclient/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,9 +776,17 @@ async fn run() -> Result<()> {
}
};

set::set(&args.socket_path, settings)
.await
.context(error::SetSnafu)?;
match set::set(&args.socket_path, settings).await {
Ok(result) => result,
Err(e) => match e {
set::Error::Raw { source: _ } => {
return Err(error::Error::Raw {
source: Box::new(e),
})
}
_ => return Err(error::Error::Set { source: e }),
},
};
}

Subcommand::Update(subcommand) => match subcommand {
Expand Down Expand Up @@ -905,6 +913,12 @@ mod error {
source: Box<apiclient::Error>,
},

// This type of error just returns the source.
#[snafu(display("{}", source))]
Raw {
#[snafu(source(from(apiclient::set::Error, Box::new)))]
source: Box<apiclient::set::Error>,
},
#[snafu(display("Failed to get report: {}", source))]
Report { source: report::Error },

Expand All @@ -924,4 +938,5 @@ mod error {
UpdateCheck { source: update::Error },
}
}

type Result<T> = std::result::Result<T, error::Error>;
28 changes: 25 additions & 3 deletions sources/api/apiclient/src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@ where
SettingsInput::Json(value) => (format!("/settings?tx={}", transaction), value),
};
let method = "PATCH";
let (_status, _body) = crate::raw_request(&socket_path, &uri, method, Some(settings_data))
.await
.context(error::RequestSnafu { uri, method })?;
let (_status, _body) =
match crate::raw_request(&socket_path, &uri, method, Some(settings_data)).await {
Ok(result) => result,
Err(e) => match e {
crate::Error::Raw { body } => {
return Err(Error::Raw {
source: Box::new(crate::Error::Raw { body }),
})
}
_ => {
return Err(Error::Request {
method: method.to_string(),
uri,
source: Box::new(e),
})
}
},
};

// Commit the transaction and apply it to the system.
let uri = format!("/tx/commit_and_apply?tx={}", transaction);
Expand Down Expand Up @@ -49,6 +64,13 @@ mod error {
#[snafu(source(from(crate::Error, Box::new)))]
source: Box<crate::Error>,
},

// This type of error just returns the source.
#[snafu(display("{}", source))]
Raw {
#[snafu(source(from(crate::Error, Box::new)))]
source: Box<crate::Error>,
},
}
}
pub use error::Error;
Expand Down
5 changes: 5 additions & 0 deletions sources/api/apiclient/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"settings": {
"motd": "test"
}
}

0 comments on commit 02ee61d

Please sign in to comment.