Skip to content

Commit

Permalink
Return correct error variants for API errors
Browse files Browse the repository at this point in the history
Previously, the generated code did not properly take into account the
HTTP status of error responses.  We would either return
*Error::UnknownError (if the response message was set) or a serde error
otherwise.

With this patch, we map the status codes to the corresponding error
variants and skip deserialization if the response body is empty.

Fixes: #30
  • Loading branch information
robin-nitrokey committed Sep 9, 2024
1 parent bd34dbf commit 7a6732a
Show file tree
Hide file tree
Showing 4 changed files with 1,627 additions and 190 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

-
- Return correct error variants for API errors ([#30](https://github.com/Nitrokey/nethsm-sdk-rs/issues/30))

[All Changes](https://github.com/Nitrokey/nethsm-sdk-rs/compare/v1.1.0...HEAD)

Expand Down
31 changes: 29 additions & 2 deletions generator/src/main/resources/crust/reqwest/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@ pub enum {{{operationIdCamelCase}}}Error {
UnknownValue(serde_json::Value),
}

impl {{{operationIdCamelCase}}}Error {
fn new(status: u16, data: &[u8]) -> Result<Self, serde_json::Error> {
// to do: support payloads once added to API spec
match status {
{{#responses}}
{{#is4xx}}
{{code}} => Ok(Self::Status{{code}}()),
{{/is4xx}}
{{#is5xx}}
{{code}} => Ok(Self::Status{{code}}()),
{{/is5xx}}
{{#isDefault}}
{{code}} => Ok(Self::DefaultResponse()),
{{/isDefault}}
{{/responses}}
_ => {
if data.is_empty() {
Ok(Self::UnknownValue(serde_json::Value::Null))
} else {
serde_json::from_slice(data).map(Self::UnknownValue)
}
}
}
}
}

{{/operation}}
{{/operations}}

Expand Down Expand Up @@ -373,7 +399,8 @@ pub fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allPar
_ => Err(err),
})?;

if local_var_resp.status() < 400 {
let local_var_status = local_var_resp.status();
if local_var_status < 400 {
{{#returnType}}
{{#vendorExtensions.x-produceMultipleMediaTypes}}
if is_json {
Expand Down Expand Up @@ -402,7 +429,7 @@ pub fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allPar
ResponseContent::unit(local_var_resp)
{{/returnType}}
} else {
ResponseContent::deserialized(local_var_resp)
ResponseContent::new(local_var_resp, |data| {{{operationIdCamelCase}}}Error::new(local_var_status, data).map_err(From::from))
.and_then(|content| Err(Error::ResponseError(content)))
}
}
Expand Down
Loading

0 comments on commit 7a6732a

Please sign in to comment.