mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 09:49:31 +02:00
Mark unrelated parsing error as warning (#1491)
* mark known parsing error as warning * add copilot suggestion * adjust unknown enum handling for json
This commit is contained in:
parent
d12e1b8549
commit
e2c3ac3146
4 changed files with 36 additions and 22 deletions
|
@ -4,7 +4,7 @@ use crate::{
|
|||
authentication::Credentials,
|
||||
dealer::{
|
||||
manager::{BoxedStream, BoxedStreamResult, Reply, RequestReply},
|
||||
protocol::{Command, Message, Request},
|
||||
protocol::{Command, FallbackWrapper, Message, Request},
|
||||
},
|
||||
session::UserAttributes,
|
||||
Error, Session, SpotifyId,
|
||||
|
@ -81,7 +81,7 @@ struct SpircTask {
|
|||
connect_state_volume_update: BoxedStreamResult<SetVolumeCommand>,
|
||||
connect_state_logout_request: BoxedStreamResult<LogoutCommand>,
|
||||
playlist_update: BoxedStreamResult<PlaylistModificationInfo>,
|
||||
session_update: BoxedStreamResult<SessionUpdate>,
|
||||
session_update: BoxedStreamResult<FallbackWrapper<SessionUpdate>>,
|
||||
connect_state_command: BoxedStream<RequestReply>,
|
||||
user_attributes_update: BoxedStreamResult<UserAttributesUpdate>,
|
||||
user_attributes_mutation: BoxedStreamResult<UserAttributesMutation>,
|
||||
|
@ -191,7 +191,7 @@ impl Spirc {
|
|||
|
||||
let session_update = session
|
||||
.dealer()
|
||||
.listen_for("social-connect/v2/session_update", Message::from_json)?;
|
||||
.listen_for("social-connect/v2/session_update", Message::try_from_json)?;
|
||||
|
||||
let user_attributes_update = session
|
||||
.dealer()
|
||||
|
@ -1552,7 +1552,24 @@ impl SpircTask {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_session_update(&mut self, mut session_update: SessionUpdate) {
|
||||
fn handle_session_update(&mut self, session_update: FallbackWrapper<SessionUpdate>) {
|
||||
// we know that this enum value isn't present in our current proto definitions, by that
|
||||
// the json parsing fails because the enum isn't known as proto representation
|
||||
const WBC: &str = "WIFI_BROADCAST_CHANGED";
|
||||
|
||||
let mut session_update = match session_update {
|
||||
FallbackWrapper::Inner(update) => update,
|
||||
FallbackWrapper::Fallback(value) => {
|
||||
let fallback_inner = value.to_string();
|
||||
if fallback_inner.contains(WBC) {
|
||||
log::debug!("Received SessionUpdate::{WBC}");
|
||||
} else {
|
||||
log::warn!("SessionUpdate couldn't be parse correctly: {value:?}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let reason = session_update.reason.enum_value();
|
||||
|
||||
let mut session = match session_update.session.take() {
|
||||
|
|
|
@ -357,7 +357,7 @@ impl DealerShared {
|
|||
}
|
||||
}
|
||||
|
||||
warn!("No subscriber for msg.uri: {}", msg.uri);
|
||||
debug!("No subscriber for msg.uri: {}", msg.uri);
|
||||
}
|
||||
|
||||
fn dispatch_request(
|
||||
|
|
|
@ -5,9 +5,8 @@ pub use request::*;
|
|||
use std::collections::HashMap;
|
||||
use std::io::{Error as IoError, Read};
|
||||
|
||||
use crate::Error;
|
||||
use base64::prelude::BASE64_STANDARD;
|
||||
use base64::{DecodeError, Engine};
|
||||
use crate::{deserialize_with::json_proto, Error};
|
||||
use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};
|
||||
use flate2::read::GzDecoder;
|
||||
use log::LevelFilter;
|
||||
use serde::Deserialize;
|
||||
|
@ -99,17 +98,19 @@ pub struct Message {
|
|||
pub uri: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum FallbackWrapper<T: protobuf::MessageFull> {
|
||||
Inner(#[serde(deserialize_with = "json_proto")] T),
|
||||
Fallback(JsonValue),
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub fn from_json<M: protobuf::MessageFull>(value: Self) -> Result<M, Error> {
|
||||
use protobuf_json_mapping::*;
|
||||
pub fn try_from_json<M: protobuf::MessageFull>(
|
||||
value: Self,
|
||||
) -> Result<FallbackWrapper<M>, Error> {
|
||||
match value.payload {
|
||||
PayloadValue::Json(json) => match parse_from_str::<M>(&json) {
|
||||
Ok(message) => Ok(message),
|
||||
Err(_) => match parse_from_str_with_options(&json, &IGNORE_UNKNOWN) {
|
||||
Ok(message) => Ok(message),
|
||||
Err(why) => Err(Error::failed_precondition(why)),
|
||||
},
|
||||
},
|
||||
PayloadValue::Json(json) => Ok(serde_json::from_str(&json)?),
|
||||
other => Err(ProtocolError::UnexpectedData(other).into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,7 @@ where
|
|||
D: Deserializer<'de>,
|
||||
{
|
||||
let v: Value = Deserialize::deserialize(de)?;
|
||||
parse_value_to_msg(&v).map_err(|why| {
|
||||
warn!("deserialize_json_proto: {v}");
|
||||
error!("deserialize_json_proto: {why}");
|
||||
Error::custom(why)
|
||||
})
|
||||
parse_value_to_msg(&v).map_err(Error::custom)
|
||||
}
|
||||
|
||||
pub fn option_json_proto<'de, T, D>(de: D) -> Result<Option<T>, D::Error>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue