fix(#3435): hive-forge issue/pr show fail on forgejo's null-for-empty reactions
Forgejo returns a bare `null` body (not `[]`) for a reactions list when nothing has reacted yet. issue_reactions/comment_reactions deserialized straight into forgejo-api's typed Vec<Reaction>, which has no null tolerance, so issue show / pr show / view failed on every item with zero reactions - i.e. nearly everything. Generalize pr_status's existing null_as_empty (same quirk, hit earlier on combined-status statuses) into a shared helper in verbs/mod.rs, and fetch reactions via the raw JSON path (Client::get_api_json) with a NullableVec<T> wrapper instead of the typed client's bare Vec<Reaction>. Also names the failing request in errors going forward, since get_api_json's error context includes the URL - closes the gap the issue itself flagged (the old error said what didn't parse but not what was fetched).
This commit is contained in:
parent
fb9cc5635a
commit
8b83eca0c1
2 changed files with 67 additions and 22 deletions
|
|
@ -12,7 +12,6 @@
|
|||
use anyhow::{Context, Result, bail};
|
||||
use clap::Args as ClapArgs;
|
||||
use forgejo_api::structs::IssueGetCommentsQuery;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::client::{Client, index};
|
||||
|
|
@ -60,23 +59,16 @@ pub fn run(client: &Client, args: Args) -> Result<()> {
|
|||
/// than `[]`, and `#[serde(default)]` only covers a *missing* key — a
|
||||
/// present null still fails to deserialize. So a doc-only repo makes the
|
||||
/// whole verb error out on exactly the PRs where "no CI here" is the
|
||||
/// answer worth printing.
|
||||
/// answer worth printing. See [`super::null_as_empty`] (shared with the
|
||||
/// reaction-listing helpers, which hit the same quirk).
|
||||
#[derive(serde::Deserialize, Default)]
|
||||
pub(crate) struct CombinedStatus {
|
||||
#[serde(default)]
|
||||
pub state: String,
|
||||
#[serde(default, deserialize_with = "null_as_empty")]
|
||||
#[serde(default, deserialize_with = "super::null_as_empty")]
|
||||
pub statuses: Vec<Value>,
|
||||
}
|
||||
|
||||
/// Deserialize a possibly-null JSON array as an empty `Vec`.
|
||||
fn null_as_empty<'de, D>(de: D) -> Result<Vec<Value>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Ok(Option::<Vec<Value>>::deserialize(de)?.unwrap_or_default())
|
||||
}
|
||||
|
||||
/// CI-only path for an explicit commit. Exit code mirrors the CI verdict.
|
||||
fn sha_status(client: &Client, sha: &str) -> Result<()> {
|
||||
let (state, statuses) = fetch_combined(client, sha)?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue