Skip to content

Commit

Permalink
abolish ErrorKind, bring in thiserror, now all Error's can be matched
Browse files Browse the repository at this point in the history
  • Loading branch information
kworr committed Aug 20, 2024
1 parent 60ecc0f commit 08eec0b
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 127 deletions.
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ default = ["openssl"]

[dependencies]
bytes = "1.0.1"
thiserror = "1.0.63"
tokio = { version = "1.2", features = ["fs", "rt"]}

tracing = "0.1.23"
Expand Down
8 changes: 4 additions & 4 deletions lib/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tracing_futures::Instrument;
use telegram_bot_raw::{HttpRequest, Request, ResponseType};

use crate::connector::{default_connector, Connector};
use crate::errors::{Error, ErrorKind};
use crate::errors::Error;
use crate::stream::UpdatesStream;

/// Main type for sending requests to the Telegram bot API.
Expand Down Expand Up @@ -130,7 +130,7 @@ impl Api {
async move {
match timeout(
duration,
api.send_http_request::<Req::Response>(request.map_err(ErrorKind::from)?),
api.send_http_request::<Req::Response>(request.map_err(Error::from)?),
)
.await
{
Expand Down Expand Up @@ -165,7 +165,7 @@ impl Api {
let api = self.clone();
let request = request.serialize();
async move {
api.send_http_request::<Req::Response>(request.map_err(ErrorKind::from)?)
api.send_http_request::<Req::Response>(request.map_err(Error::from)?)
.await
}
}
Expand All @@ -186,7 +186,7 @@ impl Api {
}, "response received"
);

let response = Resp::deserialize(http_response).map_err(ErrorKind::from)?;
let response = Resp::deserialize(http_response).map_err(Error::from)?;
tracing::trace!("response deserialized");
Ok(response)
}
Expand Down
20 changes: 10 additions & 10 deletions lib/src/connector/hyper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use telegram_bot_raw::{
};

use super::Connector;
use crate::errors::{Error, ErrorKind};
use crate::errors::Error;

#[derive(Debug)]
pub struct HyperConnector<C>(Client<C>);
Expand All @@ -48,7 +48,7 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
let client = self.0.clone();

let future = async move {
let uri = uri.map_err(HttpError::from).map_err(ErrorKind::from)?;
let uri = uri.map_err(HttpError::from).map_err(Error::from)?;

let method = match req.method {
TelegramMethod::Get => Method::GET,
Expand All @@ -63,7 +63,7 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
let content_type = "application/json"
.parse()
.map_err(HttpError::from)
.map_err(ErrorKind::from)?;
.map_err(Error::from)?;
http_request
.headers_mut()
.map(move |headers| headers.insert(CONTENT_TYPE, content_type));
Expand All @@ -84,9 +84,9 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
.and_then(|s| s.to_str())
.map(Into::into)
})
.ok_or(ErrorKind::InvalidMultipartFilename)?;
.ok_or(Error::InvalidMultipartFilename)?;

let data = tokio::fs::read(path).await.map_err(ErrorKind::from)?;
let data = tokio::fs::read(path).await.map_err(Error::from)?;
fields.push((
key,
MultipartTemporaryValue::Data {
Expand Down Expand Up @@ -119,28 +119,28 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
}
part.prepare().map_err(|err| err.error)
}
.map_err(ErrorKind::from)?;
.map_err(Error::from)?;

let boundary = prepared.boundary();

let content_type =
format!("multipart/form-data;boundary={bound}", bound = boundary)
.parse()
.map_err(HttpError::from)
.map_err(ErrorKind::from)?;
.map_err(Error::from)?;
if let Some(headers) = http_request.headers_mut() {
headers.insert(CONTENT_TYPE, content_type);
}

let mut bytes = Vec::new();
prepared.read_to_end(&mut bytes).map_err(ErrorKind::from)?;
prepared.read_to_end(&mut bytes).map_err(Error::from)?;
http_request.body(bytes.into())
}
body => panic!("Unknown body type {:?}", body),
}
.map_err(ErrorKind::from)?;
.map_err(Error::from)?;

let response = client.request(request).await.map_err(ErrorKind::from)?;
let response = client.request(request).await.map_err(Error::from)?;
let whole_chunk = to_bytes(response.into_body()).await;

let body = whole_chunk
Expand Down
69 changes: 13 additions & 56 deletions lib/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,15 @@
use std::error;
use std::fmt;

#[derive(Debug)]
pub struct Error(ErrorKind);

#[derive(Debug)]
pub enum ErrorKind {
Raw(telegram_bot_raw::Error),
Hyper(hyper::Error),
Http(hyper::http::Error),
Io(std::io::Error),
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("error from Hyper library")]
Hyper(#[from] hyper::Error),
#[error("http request error from Hyper library")]
Http(#[from] hyper::http::Error),
#[error("Invalid multipart filename")]
InvalidMultipartFilename,
#[error("ordinary IO Error")]
Io(#[from] std::io::Error),
#[error("raw error from Telegram API")]
Raw(#[from] telegram_bot_raw::Error),
}

impl From<telegram_bot_raw::Error> for ErrorKind {
fn from(error: telegram_bot_raw::Error) -> Self {
ErrorKind::Raw(error)
}
}

impl From<hyper::Error> for ErrorKind {
fn from(error: hyper::Error) -> Self {
ErrorKind::Hyper(error)
}
}

impl From<hyper::http::Error> for ErrorKind {
fn from(error: hyper::http::Error) -> Self {
ErrorKind::Http(error)
}
}

impl From<std::io::Error> for ErrorKind {
fn from(error: std::io::Error) -> Self {
ErrorKind::Io(error)
}
}

impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Error(kind)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
ErrorKind::Raw(error) => write!(f, "{}", error),
ErrorKind::Hyper(error) => write!(f, "{}", error),
ErrorKind::Http(error) => write!(f, "{}", error),
ErrorKind::Io(error) => write!(f, "{}", error),
ErrorKind::InvalidMultipartFilename => write!(f, "invalid multipart filename"),
}
}
}

impl error::Error for Error {}
2 changes: 1 addition & 1 deletion lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod types;
pub mod util;

pub use self::api::Api;
pub use self::errors::{Error, ErrorKind};
pub use self::errors::Error;
pub use prelude::*;
pub use stream::UpdatesStream;
pub use types::*;
2 changes: 1 addition & 1 deletion raw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ categories = ["api-bindings"]
license = "MIT"

[dependencies]
anyhow = "1.0.86"
bytes = "1.0"
serde = { version = "1", features = ["derive"] }
serde_derive = "1"
serde_json = "1"
serde-value = "0.7.0"
thiserror = "1.0.63"
57 changes: 9 additions & 48 deletions raw/src/requests/_base/errors.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,18 @@
use std::error;
use std::fmt;
use thiserror::Error;

use crate::types::*;

#[derive(Debug)]
pub struct Error(ErrorKind);

#[derive(Debug)]
pub enum ErrorKind {
#[derive(Error, Debug)]
pub enum Error {
#[error("Emtpy body")]
EmptyBody,
#[error("Detached error")]
DetachedError(String),
#[error("JSON ser/de error")]
Json(#[from] serde_json::Error),
#[error("Telegram error")]
TelegramError {
description: String,
parameters: Option<ResponseParameters>,
},
DetachedError(String),
Json(::serde_json::Error),
}

impl From<::serde_json::Error> for ErrorKind {
fn from(error: ::serde_json::Error) -> Self {
ErrorKind::Json(error)
}
}

impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Error(kind)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
ErrorKind::EmptyBody => write!(f, "empty body"),
ErrorKind::TelegramError {
description,
parameters,
} => {
f.write_str(description)?;
if let Some(parameters) = parameters {
if let Some(chat_id) = parameters.migrate_to_chat_id {
write!(f, ", migrate to chat id: {}", chat_id)?;
}
if let Some(seconds) = parameters.retry_after {
write!(f, ", retry after: {}", seconds)?;
}
}
Ok(())
}
ErrorKind::DetachedError(s) => f.write_str(s),
ErrorKind::Json(error) => write!(f, "{}", error),
}
}
}

impl error::Error for Error {}
1 change: 0 additions & 1 deletion raw/src/requests/_base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pub use self::_base::*;

mod errors;
pub use self::errors::Error;
pub(crate) use self::errors::ErrorKind;

mod http;
pub use self::http::{Body, Multipart, MultipartValue, RequestUrl};
Expand Down
2 changes: 1 addition & 1 deletion raw/src/requests/_base/request_types/detached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl RequestType for DetachedRequestType {
fn serialize(_options: Self::Options, request: &Self::Request) -> Result<HttpRequest, Error> {
match request {
Ok(ref req) => Ok(req.clone()),
Err(ref err) => Err(ErrorKind::DetachedError(err.to_string()).into()),
Err(ref err) => Err(Error::DetachedError(err.to_string()).into()),
}
}
}
2 changes: 1 addition & 1 deletion raw/src/requests/_base/request_types/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl<Request: Serialize> RequestType for JsonRequestType<Request> {
type Request = Request;

fn serialize(url: Self::Options, request: &Self::Request) -> Result<HttpRequest, Error> {
let body = serde_json::to_string(&request).map_err(ErrorKind::from)?;
let body = serde_json::to_string(&request).map_err(Error::from)?;
Ok(HttpRequest {
url,
method: Method::Post,
Expand Down
2 changes: 1 addition & 1 deletion raw/src/requests/_base/request_types/multipart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ macro_rules! multipart_field {
}};

($self:expr, $result:expr, $field:ident(json) => $val:expr) => {{
let s = ::serde_json::to_string($val).map_err(ErrorKind::from)?;
let s = ::serde_json::to_string($val).map_err(Error::from)?;
let value = MultipartValue::Text(s.into());
$result.push((stringify!($field), value));
}};
Expand Down
6 changes: 3 additions & 3 deletions raw/src/requests/_base/response_types/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ where

fn deserialize(resp: HttpResponse) -> Result<Self::Type, Error> {
if let Some(body) = resp.body.as_ref() {
let raw = serde_json::from_slice(body).map_err(ErrorKind::from)?;
let raw = serde_json::from_slice(body).map_err(Error::from)?;
match raw {
ResponseWrapper::Success { result } => Ok(<Self as JsonResponse>::map(result)),
ResponseWrapper::Error {
description,
parameters,
} => Err(ErrorKind::TelegramError {
} => Err(Error::TelegramError {
description,
parameters,
}
.into()),
}
} else {
Err(ErrorKind::EmptyBody.into())
Err(Error::EmptyBody.into())
}
}
}

0 comments on commit 08eec0b

Please sign in to comment.