swarm-controller: fall back to the forge diff when a file read fails, and stop rendering at the cap
A failure reading the changed files (a forge error on a tree or blob, a truncated tree, a non-base64 blob) or joining the diff task made the PR read fail, so the review posted no verdict. It now falls back to the forge's 3-line .diff with "reading the files failed: …" as the note. render wrote each file's whole diff before wide compared it with MAX_BYTES. It now writes through a writer that refuses once past the cap, which stops similar's formatter mid-file, so one huge file costs about MAX_BYTES of output, not its full diff.
This commit is contained in:
parent
2b6d480d9c
commit
f4b5e1445b
3 changed files with 82 additions and 31 deletions
|
|
@ -1248,7 +1248,8 @@ impl Client {
|
|||
/// What the review classifier reads of `owner/repo`'s PR `number`: its
|
||||
/// head commit, its commits oldest first with their full messages, and
|
||||
/// its unified diff from the merge base: [`pull_diff::wide`]'s, or the
|
||||
/// forge's `.diff` when the wide one is not read or is too large.
|
||||
/// forge's `.diff` when the wide one is not read, cannot be read, or is
|
||||
/// too large.
|
||||
///
|
||||
/// # Errors
|
||||
/// A forge failure, with the [`ForgejoError`] underneath; a 404 on the
|
||||
|
|
@ -1299,12 +1300,15 @@ impl Client {
|
|||
(Some(reason), _) => Err(reason),
|
||||
(None, None) => Err("the forge names no merge base".to_owned()),
|
||||
(None, Some(base)) => {
|
||||
let files = self
|
||||
match self
|
||||
.changed_files(owner, repo, number, &base, &head_sha)
|
||||
.await?;
|
||||
tokio::task::spawn_blocking(move || pull_diff::wide(&files))
|
||||
.await
|
||||
.context("building the PR's wide diff")?
|
||||
{
|
||||
Ok(files) => tokio::task::spawn_blocking(move || pull_diff::wide(&files))
|
||||
.await
|
||||
.unwrap_or_else(|e| Err(format!("building the wide diff failed: {e}"))),
|
||||
Err(e) => Err(format!("reading the files failed: {e:#}")),
|
||||
}
|
||||
}
|
||||
};
|
||||
let (diff, narrowed) = match wide {
|
||||
|
|
@ -2622,6 +2626,16 @@ mod tests {
|
|||
read.narrowed.as_deref(),
|
||||
Some("the forge names no merge base")
|
||||
);
|
||||
|
||||
let unreadable = r#"{"number":7,"requested_reviewers":[],"head":{"sha":"h2"},"merge_base":"mb","changed_files":1}"#;
|
||||
let (client, _) = pull_forge(unreadable, old, new).await;
|
||||
let read = client.pull_for_review("o", "r", 7).await.unwrap();
|
||||
assert_eq!(read.diff, "forge diff\n");
|
||||
let reason = read.narrowed.expect("a failed file read falls back");
|
||||
assert!(
|
||||
reason.starts_with("reading the files failed: read tree h2 of o/r"),
|
||||
"{reason}"
|
||||
);
|
||||
}
|
||||
|
||||
/// A root tree with the `.hyperhive` tree and a blob beside it.
|
||||
|
|
|
|||
Loading…
Reference in a new issue