From d4e5a05fdb0eb9d990303d645899cc5ab129e2de Mon Sep 17 00:00:00 2001 From: Reuben Wong Date: Tue, 26 Sep 2023 00:30:12 +0800 Subject: [PATCH] layout error enums --- Cargo.toml | 2 ++ src/api.rs | 1 + src/api/error.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ src/api/query.rs | 4 +++ 4 files changed, 80 insertions(+) create mode 100644 src/api/query.rs diff --git a/Cargo.toml b/Cargo.toml index 4357c26..b385ce3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,6 @@ serde = { version = "~1.0.103", features = ["derive"] } serde_json = "^1.0.25" serde_urlencoded = "~0.7" url = "^2.1" + +[dev-dependencies] dotenvy = "0.15.7" diff --git a/src/api.rs b/src/api.rs index 8a0e211..cbc0287 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,4 +1,5 @@ mod endpoint; mod error; +mod query; pub use self::error::BodyError; diff --git a/src/api/error.rs b/src/api/error.rs index d94ae09..1a1cbc2 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -3,6 +3,8 @@ // This file may not be copied, modified, or distributed // except according to those terms. +use std::error::Error; + use thiserror::Error; /// Errors which may occur when creating form data. @@ -17,3 +19,74 @@ pub enum BodyError { source: serde_urlencoded::ser::Error, }, } + +/// Errors which may occur when using API endpoints. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum ApiError +where + E: Error + Send + Sync + 'static, +{ + /// The client encountered an error. + #[error("client error: {}", source)] + Client { + /// The client error. + source: E, + }, + /// The URL failed to parse. + #[error("failed to parse URL: {}", source)] + UrlParse { + /// The source of the error. + #[from] + source: url::ParseError, + }, + /// Body data could not be created. + #[error("failed to create request body: {}", source)] + Body { + /// The source of the error. + #[from] + source: BodyError, + }, + /// JSON deserialization from Marketstack failed. + #[error("could not parse JSON response: {}", source)] + Json { + /// The source of the error. + #[from] + source: serde_json::Error, + }, + /// Marketstack returned an error message. + #[error("marketstack server error: {}", msg)] + Marketstack { + /// The error message from Marketstack. + msg: String, + }, + /// Marketstack returned an error without JSON information. + #[error("marketstack internal server error: {}", status)] + MarketstackService { + /// The status code for the return. + status: http::StatusCode, + /// The error data from Marketstack. + data: Vec, + }, + /// Marketstack returned an error object. + #[error("marketstack server error: {:?}", obj)] + MarketstackObject { + /// The error object from Marketstack. + obj: serde_json::Value, + }, + /// Marketstack returned an HTTP error with JSON we did not recognize. + #[error("marketstack server error: {:?}", obj)] + MarketstackUnrecognized { + /// The full object from Marketstack. + obj: serde_json::Value, + }, + /// Failed to parse an expected data type from JSON. + #[error("could not parse {} data from JSON: {}", typename, source)] + DataType { + /// The source of the error. + source: serde_json::Error, + /// The name of the type that could not be deserialized. + typename: &'static str, + }, + // TODO: implement pagination error +} diff --git a/src/api/query.rs b/src/api/query.rs new file mode 100644 index 0000000..fea8d11 --- /dev/null +++ b/src/api/query.rs @@ -0,0 +1,4 @@ +// Licensed under the MIT license +// . +// This file may not be copied, modified, or distributed +// except according to those terms.