From e2780e0965b2a452b2eceee02978b3f99c857a2c Mon Sep 17 00:00:00 2001 From: Stephen Leitnick Date: Sat, 9 Dec 2023 14:40:59 -0500 Subject: [PATCH] Better HTTP error messages --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- docs/cli/cli-install.md | 4 +-- docs/lib/lib-install.md | 2 +- src/rbx/experience.rs | 59 +++++++++++++++++------------------------ 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1a6fb1..e9d4d2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,7 +661,7 @@ dependencies = [ [[package]] name = "rbxcloud" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 88e8e1b..60aa6fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rbxcloud" -version = "0.6.0" +version = "0.6.1" description = "CLI and SDK for the Roblox Open Cloud APIs" authors = ["Stephen Leitnick"] license = "MIT" diff --git a/README.md b/README.md index b4df4ec..a01cb7d 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The library built for the CLI tool is available to use directly in Rust projects To use `rbxcloud` in a Rust project, simply add `rbxcloud` to the `Cargo.toml` dependency list. ```toml [dependencies] -rbxcloud = "0.6.0" +rbxcloud = "0.6.1" ``` Alternatively, use `cargo add`. diff --git a/docs/cli/cli-install.md b/docs/cli/cli-install.md index 2e244a8..5d64818 100644 --- a/docs/cli/cli-install.md +++ b/docs/cli/cli-install.md @@ -7,7 +7,7 @@ There are a few different ways to install the `rbxcloud` CLI. ### [Aftman](https://github.com/LPGhatguy/aftman) (Preferred) Run the `aftman add` command within your project directory. This will add `rbxcloud` to the project's `aftman.toml` file (or create one if it doesn't yet exist). ```sh -$ aftman add Sleitnick/rbxcloud@0.6.0 +$ aftman add Sleitnick/rbxcloud@0.6.1 ``` Next, run `aftman install` to install `rbxcloud`. @@ -17,7 +17,7 @@ Add `rbxcloud` under the `[tools]` section of your `foreman.toml` file. ```toml # foreman.toml [tools] -rbxcloud = { github = "Sleitnick/rbxcloud", version = "0.6.0" } +rbxcloud = { github = "Sleitnick/rbxcloud", version = "0.6.1" } ``` Next, run `foreman install` to install `rbxcloud`. diff --git a/docs/lib/lib-install.md b/docs/lib/lib-install.md index 9779eea..56c45fb 100644 --- a/docs/lib/lib-install.md +++ b/docs/lib/lib-install.md @@ -5,7 +5,7 @@ To use `rbxcloud` in a Rust project, simply add `rbxcloud` to the `Cargo.toml` dependency list. ```toml [dependencies] -rbxcloud = "0.6.0" +rbxcloud = "0.6.1" ``` Alternatively, use `cargo add`. diff --git a/src/rbx/experience.rs b/src/rbx/experience.rs index 7127245..49c44a1 100644 --- a/src/rbx/experience.rs +++ b/src/rbx/experience.rs @@ -43,6 +43,12 @@ pub struct PublishExperienceResponse { pub version_number: u64, } +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct PublishExperienceErrorResponse { + message: String, +} + /// Publish a place under a specific experience. pub async fn publish_experience( params: &PublishExperienceParams, @@ -55,6 +61,7 @@ pub async fn publish_experience( placeId=params.place_id, versionType=params.version_type, ); + let res = client .post(url) .header("x-api-key", ¶ms.api_key) @@ -63,44 +70,28 @@ pub async fn publish_experience( .send() .await?; let status = res.status(); + if !status.is_success() { let code = status.as_u16(); - if code == 400 { - return Err(Error::HttpStatusError { - code, - msg: "invalid request or file content".to_string(), - }); - } else if code == 401 { - return Err(Error::HttpStatusError { - code, - msg: "api key not valid for operation".to_string(), - }); - } else if code == 403 { - return Err(Error::HttpStatusError { - code, - msg: "publish not allowed on place".to_string(), - }); - } else if code == 404 { - return Err(Error::HttpStatusError { - code, - msg: "place or universe does not exist".to_string(), - }); - } else if code == 409 { - return Err(Error::HttpStatusError { - code, - msg: "place not part of the universe".to_string(), - }); - } else if code == 500 { - return Err(Error::HttpStatusError { + let msg_text = res.text().await; + let msg_json = msg_text + .map(|txt| { + serde_json::from_str::(txt.as_str()) + .unwrap_or(PublishExperienceErrorResponse { message: txt }) + }) + .map(|err| err.message); + + let msg = msg_json.unwrap_or(status.canonical_reason().unwrap_or_default().to_string()); + + return match code { + 400 | 401 | 403 | 404 | 409 | 500 => Err(Error::HttpStatusError { code, msg }), + _ => Err(Error::HttpStatusError { code, - msg: "internal server error".to_string(), - }); - } - return Err(Error::HttpStatusError { - code, - msg: status.canonical_reason().unwrap_or_default().to_string(), - }); + msg: status.canonical_reason().unwrap_or_default().to_string(), + }), + }; } + let body = res.json::().await?; Ok(body) }