fix(#2851): warn when the state read breaks but the write still works
argus's review note: current_room_state collapsed absent-state, transport failure and an unparseable body into one None, so a systematically failing GET was unobservable. Only one of the three actually hides. A transport error takes the PUT down with it one line later, and a 404 is the expected first-setup case — both stay at debug. A non-404 HTTP failure is the silent one: the read is broken while the write still succeeds, so the guard switches off and the sweep resumes emitting with nothing to show for it. That case, and only that case, warns. Keeping the warn narrow is the point: one that also fired on every expected 404 would train the reader to skip the line.
This commit is contained in:
parent
81292f14b6
commit
f4c470881e
1 changed files with 31 additions and 3 deletions
|
|
@ -1234,16 +1234,44 @@ fn state_needs_write(current: Option<&serde_json::Value>, desired: &serde_json::
|
|||
/// Read the room's current content for one state event. `None` on any
|
||||
/// failure — absent state, transport error, or an unparseable body are
|
||||
/// all "we don't know", and [`state_needs_write`] turns that into a write.
|
||||
///
|
||||
/// One failure is louder than the rest, and it is the only one that hides:
|
||||
/// **a non-404 HTTP failure means the read broke while the write still
|
||||
/// works**, so the guard degrades to writing every time and the sweep
|
||||
/// resumes waking the hive with nothing else to show for it. A transport
|
||||
/// error needs no warning of its own — the PUT immediately after it fails
|
||||
/// too, loudly — and a 404 is the expected first-setup case.
|
||||
async fn current_room_state(
|
||||
client: &reqwest::Client,
|
||||
admin_token: &str,
|
||||
url: &str,
|
||||
) -> Option<serde_json::Value> {
|
||||
let resp = client.get(url).bearer_auth(admin_token).send().await.ok()?;
|
||||
if !resp.status().is_success() {
|
||||
let resp = match client.get(url).bearer_auth(admin_token).send().await {
|
||||
Ok(resp) => resp,
|
||||
Err(e) => {
|
||||
tracing::debug!(error = ?e, url, "matrix: state read unreachable; writing");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let status = resp.status();
|
||||
if !status.is_success() {
|
||||
if status != reqwest::StatusCode::NOT_FOUND {
|
||||
tracing::warn!(
|
||||
%status,
|
||||
url,
|
||||
"matrix: state read failed while writes still work — the \
|
||||
skip-if-unchanged guard is off and every sweep will re-emit"
|
||||
);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
resp.json::<serde_json::Value>().await.ok()
|
||||
match resp.json::<serde_json::Value>().await {
|
||||
Ok(body) => Some(body),
|
||||
Err(e) => {
|
||||
tracing::debug!(error = ?e, url, "matrix: state read body unparseable; writing");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PUT a state event into `room_id` using the admin token, **skipping the
|
||||
|
|
|
|||
Loading…
Reference in a new issue