Merge remote-tracking branch 'origin/rework-dispatching' into rework-dispatching

This commit is contained in:
p0lunin 2020-02-11 21:46:56 +02:00
commit ce48e211a2
3 changed files with 65 additions and 5 deletions

View file

@ -155,6 +155,22 @@ pub fn polling(
let updates = match req.send().await {
Err(err) => vec![Err(err)],
Ok(updates) => {
let updates = updates
.into_iter()
.filter(|update| match update {
Err(error) => {
log::error!("Cannot parse an update: {:?}! \
This is a bug in teloxide, please open an issue here: \
https://github.com/teloxide/teloxide/issues.", error);
false
}
Ok(_) => true,
})
.map(|update| {
update.expect("See the previous .filter() call")
})
.collect::<Vec<Update>>();
if let Some(upd) = updates.last() {
offset = upd.id + 1;
}

View file

@ -4,8 +4,9 @@ use crate::{
net,
requests::{Request, ResponseResult},
types::{AllowedUpdate, Update},
Bot,
Bot, RequestError,
};
use serde_json::Value;
use std::sync::Arc;
/// Use this method to receive incoming updates using long polling ([wiki]).
@ -31,16 +32,30 @@ pub struct GetUpdates {
#[async_trait::async_trait]
impl Request for GetUpdates {
type Output = Vec<Update>;
type Output = Vec<serde_json::Result<Update>>;
async fn send(&self) -> ResponseResult<Vec<Update>> {
net::request_json(
/// Deserialize to `Vec<serde_json::Result<Update>>` instead of
/// `Vec<Update>`, because we want to parse the rest of updates even if our
/// library hasn't parsed one.
async fn send(&self) -> ResponseResult<Vec<serde_json::Result<Update>>> {
let value: Value = net::request_json(
self.bot.client(),
self.bot.token(),
"getUpdates",
&self,
)
.await
.await?;
match value {
Value::Array(array) => Ok(array
.into_iter()
.map(|value| serde_json::from_str(&value.to_string()))
.collect()),
_ => Err(RequestError::InvalidJson(
serde_json::from_value::<Vec<Update>>(value)
.expect_err("get_update must return Value::Array"),
)),
}
}
}

View file

@ -176,4 +176,33 @@ mod test {
let actual = serde_json::from_str::<Update>(json).unwrap();
assert_eq!(expected, actual);
}
#[test]
fn de_private_chat_text_message() {
let text = r#"
{
"message": {
"chat": {
"first_name": "Hirrolot",
"id": 408258968,
"type": "private",
"username": "hirrolot"
},
"date": 1581448857,
"from": {
"first_name": "Hirrolot",
"id": 408258968,
"is_bot": false,
"language_code": "en",
"username": "hirrolot"
},
"message_id": 154,
"text": "4"
},
"update_id": 306197398
}
"#;
assert!(serde_json::from_str::<Update>(text).is_ok());
}
}