fix: Don't halt and catch fire on deserialization errors in MSC4133 migration

This commit is contained in:
Ginger
2025-12-12 11:16:52 -05:00
parent 6a8b988b36
commit 7345c241a9
+24 -16
View File
@@ -590,6 +590,10 @@ async fn fix_readreceiptid_readreceipt_duplicates(services: &Services) -> Result
const FIXED_CORRUPT_MSC4133_FIELDS_MARKER: &[u8] = b"fix_corrupt_msc4133_fields"; const FIXED_CORRUPT_MSC4133_FIELDS_MARKER: &[u8] = b"fix_corrupt_msc4133_fields";
async fn fix_corrupt_msc4133_fields(services: &Services) -> Result { async fn fix_corrupt_msc4133_fields(services: &Services) -> Result {
// Due to an old bug, some conduwuit databases have `us.cloke.msc4175.tz` user
// profile fields with raw strings instead of quoted JSON ones.
// This migration fixes that.
use serde_json::{Value, from_slice}; use serde_json::{Value, from_slice};
type KeyVal<'a> = ((OwnedUserId, String), &'a [u8]); type KeyVal<'a> = ((OwnedUserId, String), &'a [u8]);
@@ -606,24 +610,28 @@ async fn fix_corrupt_msc4133_fields(services: &Services) -> Result {
async |(mut total, mut fixed), async |(mut total, mut fixed),
((user, key), value): KeyVal<'_>| ((user, key), value): KeyVal<'_>|
-> Result<(usize, usize)> { -> Result<(usize, usize)> {
if let Err(error) = from_slice::<Value>(value) { match from_slice::<Value>(value) {
// Due to an old bug, some conduwuit databases have `us.cloke.msc4175.tz` user // corrupted timezone field
// profile fields with raw strings instead of quoted JSON ones. | Err(_) if key == "us.cloke.msc4175.tz" => {
// This migration fixes that. let new_value = Value::String(String::from_utf8(value.to_vec())?);
let new_value = if key == "us.cloke.msc4175.tz" { useridprofilekey_value.put((user, key), Json(new_value));
Value::String(String::from_utf8(value.to_vec())?) fixed = fixed.saturating_add(1);
} else { },
return Err!( // corrupted value for some other key
"failed to deserialize msc4133 key {} of user {}: {}", | Err(error) => {
key, warn!(
user, "deleting MSC4133 key {} for user {} due to deserialization \
error failure: {}",
key, user, error
); );
}; useridprofilekey_value.del((user, key));
},
useridprofilekey_value.put((user, key), Json(new_value)); // other key with no issues
fixed = fixed.saturating_add(1); | Ok(_) => {
// do nothing
},
} }
total = total.saturating_add(1); total = total.saturating_add(1);
Ok((total, fixed)) Ok((total, fixed))