1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-03 01:39:28 +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:
Felix Prillwitz 2025-05-03 23:39:07 +02:00 committed by GitHub
parent d12e1b8549
commit e2c3ac3146
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 22 deletions

View file

@ -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() {

View file

@ -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(

View file

@ -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()),
}
}

View file

@ -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>