Merge pull request #241 from teloxide/download_error_and_from

Implement `From<_> for RequestError` for more types
This commit is contained in:
Waffle Maybe 2022-08-15 11:46:56 +04:00 committed by GitHub
commit 61d36e3ac9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 19 deletions

View file

@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## unreleased ## unreleased
### Added
- `From<ApiError>`, `From<DownloadError>` and `From<std::io::Error>` impls for `RequestError` ([#241][pr241])
[pr241]: https://github.com/teloxide/teloxide-core/pull/241
## 0.7.0 - 2022-07-19 ## 0.7.0 - 2022-07-19
### Added ### Added
@ -117,7 +123,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- `errors` module and `errors::AsResponseParameters` trait ([#130][pr130]) - `errors` module and `errors::AsResponseParameters` trait ([#130][pr130])
- `UserId::{url, is_anonymous, is_channel, is_telegram}` convenience functions ([#197][pr197]) - `UserId::{url, is_anonymous, is_channel, is_telegram}` convenience functions ([#197][pr197])
- `User::{tme_url, preferably_tme_url}` convenience functions ([#197][pr197]) - `User::{tme_url, preferably_tme_url}` convenience functions ([#197][pr197])
- `Me::username` and `Deref<Target = User>` implementation for `Me` ([#197][pr197]) - `Me::username` and `Deref<Target = User>` implementation for `Me` ([#197][pr197])
- `Me::{mention, tme_url}` ([#197][pr197]) - `Me::{mention, tme_url}` ([#197][pr197])
@ -337,7 +343,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `DefaultParseMode::parse_mode` which allows to get currently used default parse mode ([#77][pr77]) - `DefaultParseMode::parse_mode` which allows to get currently used default parse mode ([#77][pr77])
- `Thrrotle::{limits,set_limits}` functions ([#77][pr77]) - `Thrrotle::{limits,set_limits}` functions ([#77][pr77])
- `Throttle::{with_settings,spawn_with_settings}` and `throttle::Settings` ([#96][pr96]) - `Throttle::{with_settings,spawn_with_settings}` and `throttle::Settings` ([#96][pr96])
- Getters for fields nested in `Chat` ([#80][pr80]) - Getters for fields nested in `Chat` ([#80][pr80])
- API errors: `ApiError::NotEnoughRightsToManagePins`, `ApiError::BotKickedFromSupergroup` ([#84][pr84]) - API errors: `ApiError::NotEnoughRightsToManagePins`, `ApiError::BotKickedFromSupergroup` ([#84][pr84])
- Telegram bot API 5.2 support ([#86][pr86]) - Telegram bot API 5.2 support ([#86][pr86])
- Telegram bot API 5.3 support ([#99][pr99]) - Telegram bot API 5.3 support ([#99][pr99])
@ -355,7 +361,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- `Message::url` now returns links to messages in private groups too ([#80][pr80]) - `Message::url` now returns links to messages in private groups too ([#80][pr80])
- Refactor `ChatMember` methods ([#74][pr74]) - Refactor `ChatMember` methods ([#74][pr74])
- impl `Deref<Target = ChatMemberKind>` to make `ChatMemberKind`'s methods callable directly on `ChatMember` - impl `Deref<Target = ChatMemberKind>` to make `ChatMemberKind`'s methods callable directly on `ChatMember`
- Add `ChatMemberKind::is_{creator,administrator,member,restricted,left,kicked}` which check `kind` along with `is_privileged` and `is_in_chat` which combine some of the above. - Add `ChatMemberKind::is_{creator,administrator,member,restricted,left,kicked}` which check `kind` along with `is_privileged` and `is_in_chat` which combine some of the above.
@ -369,8 +375,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- telegram_response: fix issue `retry_after` and `migrate_to_chat_id` handling ([#94][pr94]) - telegram_response: fix issue `retry_after` and `migrate_to_chat_id` handling ([#94][pr94])
- Type of `PublicChatSupergroup::slow_mode_delay` field: `Option<i32>`=> `Option<u32>` ([#80][pr80]) - Type of `PublicChatSupergroup::slow_mode_delay` field: `Option<i32>`=> `Option<u32>` ([#80][pr80])
- Add missing `Chat::message_auto_delete_time` field ([#80][pr80]) - Add missing `Chat::message_auto_delete_time` field ([#80][pr80])
- Output types of `LeaveChat` `PinChatMessage`, `SetChatDescription`, `SetChatPhoto` `SetChatTitle`, `UnpinAllChatMessages` and `UnpinChatMessage`: `String` => `True` ([#79][pr79]) - Output types of `LeaveChat` `PinChatMessage`, `SetChatDescription`, `SetChatPhoto` `SetChatTitle`, `UnpinAllChatMessages` and `UnpinChatMessage`: `String` => `True` ([#79][pr79])
- `SendChatAction` output type `Message` => `True` ([#75][pr75]) - `SendChatAction` output type `Message` => `True` ([#75][pr75])
- `GetChatAdministrators` output type `ChatMember` => `Vec<ChatMember>` ([#73][pr73]) - `GetChatAdministrators` output type `ChatMember` => `Vec<ChatMember>` ([#73][pr73])
@ -396,7 +402,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 0.2.1 - 2020-03-19 ## 0.2.1 - 2020-03-19
### Fixed ### Fixed
- Types fields privacy (make fields of some types public) ([#68][pr68]) - Types fields privacy (make fields of some types public) ([#68][pr68])
- `Dice::{emoji, value}` - `Dice::{emoji, value}`
@ -451,7 +457,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- `NonStrictVec` -> `SemiparsedVec`. - `NonStrictVec` -> `SemiparsedVec`.
## 0.1.1 - 2020-02-17 ## 0.1.1 - 2020-02-17
@ -483,16 +489,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Output<T>` alias to `<<T as HasPayload>::Payload as Payload>::Output` - `Output<T>` alias to `<<T as HasPayload>::Payload as Payload>::Output`
- `Payload`, `HasPayload` and `Request` traits which represent different parts of the request ([#5][pr5]) - `Payload`, `HasPayload` and `Request` traits which represent different parts of the request ([#5][pr5])
- `GetUpdatesNonStrict` 'telegram' method, that behaves just like `GetUpdates` but doesn't [#2][pr2] - `GetUpdatesNonStrict` 'telegram' method, that behaves just like `GetUpdates` but doesn't [#2][pr2]
fail if one of updates fails to be deserialized fail if one of updates fails to be deserialized
- Move core code here from the [`teloxide`] main repo, for older changes see it's [`CHANGELOG.md`]. - Move core code here from the [`teloxide`] main repo, for older changes see it's [`CHANGELOG.md`].
- Following modules were moved: - Following modules were moved:
- `bot` - `bot`
- `requests` [except `requests::respond` function] - `requests` [except `requests::respond` function]
- `types` - `types`
- `errors` - `errors`
- `net` [private] - `net` [private]
- `client_from_env` was moved from `teloxide::utils` to crate root of `teloxide-core` - `client_from_env` was moved from `teloxide::utils` to crate root of `teloxide-core`
- To simplify `GetUpdates` request it was changed to simply return `Vec<Update>` - To simplify `GetUpdates` request it was changed to simply return `Vec<Update>`
(instead of `Vec<Result<Update, (Value, serde_json::Error)>>`) (instead of `Vec<Result<Update, (Value, serde_json::Error)>>`)
[pr2]: https://github.com/teloxide/teloxide-core/pull/2 [pr2]: https://github.com/teloxide/teloxide-core/pull/2
@ -523,8 +529,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Make `net` module public - Make `net` module public
- Move `Bot::download_file{,_stream}` methods to a new `Download` trait - Move `Bot::download_file{,_stream}` methods to a new `Download` trait
- Impl `Download` for all bot adaptors & the `Bot` itself - Impl `Download` for all bot adaptors & the `Bot` itself
- Change return type of `download_file_stream` — return `Stream<Result<Bytes>>``, - Change return type of `download_file_stream` — return ` Stream<Result<Bytes>>``, instead of `Future<Result<Stream<Result<Bytes>>>>``
instead of `Future<Result<Stream<Result<Bytes>>>>``
- Add `api_url` param to standalone versions of `download_file{,_stream}` - Add `api_url` param to standalone versions of `download_file{,_stream}`
- Make `net::{TELEGRAM_API_URL, download_file{,_stream}}` pub - Make `net::{TELEGRAM_API_URL, download_file{,_stream}}` pub
- Refactor `Bot` ([#29][pr29]): - Refactor `Bot` ([#29][pr29]):
@ -565,7 +570,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[pr4]: https://github.com/teloxide/teloxide-core/pull/4 [pr4]: https://github.com/teloxide/teloxide-core/pull/4
[pr44]: https://github.com/teloxide/teloxide-core/pull/44 [pr44]: https://github.com/teloxide/teloxide-core/pull/44
[`teloxide`]: https://github.com/teloxide/teloxide [`teloxide`]: https://github.com/teloxide/teloxide
[`CHANGELOG.md`]: https://github.com/teloxide/teloxide/blob/master/CHANGELOG.md [`changelog.md`]: https://github.com/teloxide/teloxide/blob/master/CHANGELOG.md

View file

@ -12,7 +12,7 @@ use crate::types::ResponseParameters;
pub enum RequestError { pub enum RequestError {
/// A Telegram API error. /// A Telegram API error.
#[error("A Telegram's error: {0}")] #[error("A Telegram's error: {0}")]
Api(#[source] ApiError), Api(#[from] ApiError),
/// The group has been migrated to a supergroup with the specified /// The group has been migrated to a supergroup with the specified
/// identifier. /// identifier.
@ -26,7 +26,7 @@ pub enum RequestError {
/// Network error while sending a request to Telegram. /// Network error while sending a request to Telegram.
#[error("A network error: {0}")] #[error("A network error: {0}")]
// NOTE: this variant must not be created by anything except the From impl // NOTE: this variant must not be created by anything except the explicit From impl
Network(#[source] reqwest::Error), Network(#[source] reqwest::Error),
/// Error while parsing a response from Telegram. /// Error while parsing a response from Telegram.
@ -45,7 +45,7 @@ pub enum RequestError {
/// Occurs when trying to send a file to Telegram. /// Occurs when trying to send a file to Telegram.
#[error("An I/O error: {0}")] #[error("An I/O error: {0}")]
Io(#[source] io::Error), Io(#[from] io::Error),
} }
/// An error caused by downloading a file. /// An error caused by downloading a file.
@ -53,7 +53,7 @@ pub enum RequestError {
pub enum DownloadError { pub enum DownloadError {
/// A network error while downloading a file from Telegram. /// A network error while downloading a file from Telegram.
#[error("A network error: {0}")] #[error("A network error: {0}")]
// NOTE: this variant must not be created by anything except the From impl // NOTE: this variant must not be created by anything except the explicit From impl
Network(#[source] reqwest::Error), Network(#[source] reqwest::Error),
/// An I/O error while writing a file to destination. /// An I/O error while writing a file to destination.
@ -762,6 +762,32 @@ pub enum ApiError {
Unknown(String), Unknown(String),
} }
/// This impl allows to use `?` to propagate [`DownloadError`]s in function
/// returning [`RequestError`]s. For example:
///
/// ```rust
/// # use teloxide_core::errors::{DownloadError, RequestError};
///
/// async fn handler() -> Result<(), RequestError> {
/// download_file().await?; // `?` just works
///
/// Ok(())
/// }
///
/// async fn download_file() -> Result<(), DownloadError> {
/// /* download file here */
/// Ok(())
/// }
/// ```
impl From<DownloadError> for RequestError {
fn from(download_err: DownloadError) -> Self {
match download_err {
DownloadError::Network(err) => RequestError::Network(err),
DownloadError::Io(err) => RequestError::Io(err),
}
}
}
impl From<reqwest::Error> for DownloadError { impl From<reqwest::Error> for DownloadError {
fn from(error: reqwest::Error) -> Self { fn from(error: reqwest::Error) -> Self {
DownloadError::Network(hide_token(error)) DownloadError::Network(hide_token(error))