Fix 'Cannot serialize NaN as google.protobuf.Value.number_value'.

In case the codec returns a NaN float, this is converted to None to
avoid Protobuf serialization error. This also fixes the eventlog such
that it does not break out of the loop (unless it is a channel error).
Messages that can't be processed will be ignored and an error is
printed.

Fixes https://github.com/chirpstack/chirpstack-v3-to-v4/issues/4.
This commit is contained in:
Orne Brocaar
2022-10-06 12:31:11 +01:00
parent 5f4d03f3e4
commit e04f991e76
2 changed files with 215 additions and 194 deletions

View File

@ -14,9 +14,15 @@ fn _rquickjs_to_struct_val(val: &rquickjs::Value) -> Option<pbjson_types::value:
rquickjs::Type::Int => Some(pbjson_types::value::Kind::NumberValue( rquickjs::Type::Int => Some(pbjson_types::value::Kind::NumberValue(
val.as_int().unwrap().into(), val.as_int().unwrap().into(),
)), )),
rquickjs::Type::Float => Some(pbjson_types::value::Kind::NumberValue( rquickjs::Type::Float => {
val.as_float().unwrap(), let v = val.as_float().unwrap();
)), if v.is_nan() {
// Avoid Cannot serialize NaN as google.protobuf.Value.number_value error.
None
} else {
Some(pbjson_types::value::Kind::NumberValue(v))
}
}
rquickjs::Type::String => Some(pbjson_types::value::Kind::StringValue( rquickjs::Type::String => Some(pbjson_types::value::Kind::StringValue(
val.as_string().unwrap().to_string().unwrap(), val.as_string().unwrap().to_string().unwrap(),
)), )),

View File

@ -96,6 +96,7 @@ pub async fn get_event_logs(
for stream_id in &stream_key.ids { for stream_id in &stream_key.ids {
last_id = stream_id.id.clone(); last_id = stream_id.id.clone();
for (k, v) in &stream_id.map { for (k, v) in &stream_id.map {
let res = || -> Result<()> {
match k.as_ref() { match k.as_ref() {
"up" => { "up" => {
trace!(key = %k, id = %last_id, "Event-log received from stream"); trace!(key = %k, id = %last_id, "Event-log received from stream");
@ -300,6 +301,20 @@ pub async fn get_event_logs(
_ => { _ => {
error!(key = %k, "Unexpected key in in event-log stream"); error!(key = %k, "Unexpected key in in event-log stream");
} }
}
Ok(())
}();
if let Err(e) = res {
// Return in case of channel error, in any other case we just log
// the error.
if e.downcast_ref::<mpsc::error::SendError<api::LogItem>>().is_some() {
return Err(e);
}
error!(key = %k, error = %e, "Parsing frame-log error");
} }
} }
} }