Skip to content

fix(ipni): preserve failure reason in deal-flow rethrow#490

Merged
SgtPooki merged 2 commits into
mainfrom
fix/ipni-failure-reason-in-rethrow
Apr 28, 2026
Merged

fix(ipni): preserve failure reason in deal-flow rethrow#490
SgtPooki merged 2 commits into
mainfrom
fix/ipni-failure-reason-in-rethrow

Conversation

@SgtPooki
Copy link
Copy Markdown
Collaborator

Summary

  • Closes IPNI xxx root CID not verified #473
  • One-line change: pass ipniResult.failedCIDs[0].reason through to the rethrow at apps/backend/src/deal-addons/strategies/ipni.strategy.ts:248 so the outer ipni_tracking_failed log carries the actual reason instead of root CID not verified
  • Today, every IPNI breach (timeout, missing expected provider, HTTP fetch error, parse error) ends up with the same generic message in BS, even though one log-line earlier ipni_root_cid_verification_failed already populates a failureReason field correctly. The outer log loses it during rethrow.

Why

beck-8 reported that the generic message makes SP-side troubleshooting impossible. After this PR, the same failed deal will surface "IPNI verification timed out after 60000ms" / "Missing expected provider(s): ..." / "Failed to query IPNI indexer: ..." at the catch site instead of "root CID not verified".

See dealbot#473 audit comment: #473 (comment) for the full investigation including evidence that all visible IPNI failures are real SLO breaches with reasons that are already captured by the verify code path but lost at this single rethrow.

Test plan

  • pnpm exec vitest run src/deal-addons/strategies/ipni.strategy.spec.ts -> 11/11 pass (no test asserts on the old message string)
  • No behavior change at the IpniStatus / Deal entity level: still throws, still marks IpniStatus.FAILED, still records failure.timedout metric. Only the error message changes.
  • Manual: post-deploy, confirm ipni_tracking_failed events in BS now show failureReason content matching ipni_root_cid_verification_failed for the same deal.

The rethrow at the deal-flow IPNI verification site swallowed
ipniResult.failedCIDs[0].reason, so the outer ipni_tracking_failed
log only showed "root CID not verified" regardless of why
verification actually failed (timeout vs missing expected
provider vs HTTP fetch error vs parse error).

Pass the underlying reason through so SPs and operators can
self-diagnose IPNI breaches without filing tickets.

Closes #473
Copilot AI review requested due to automatic review settings April 28, 2026 14:44
@FilOzzy FilOzzy added this to FOC Apr 28, 2026
@github-project-automation github-project-automation Bot moved this to 📌 Triage in FOC Apr 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves observability for IPNI deal-flow failures by preserving and rethrowing the underlying IPNI verification failure reason so downstream/outer logs (e.g., ipni_tracking_failed) surface actionable error details instead of the generic “root CID not verified”.

Changes:

  • Include ipniResult.failedCIDs[0]?.reason in the thrown error message when rootCIDVerified is false (with a fallback to the prior generic message).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/backend/src/deal-addons/strategies/ipni.strategy.ts Outdated
Carry the underlying failure reason via the native Error.cause field
rather than concatenating it into the message. toStructuredError
already recurses through cause (MAX_CAUSE_DEPTH=5), so the structured
log will surface { error.message: "...root CID not verified",
error.cause.message: "IPNI verification timed out after 60000ms" }.

Cleaner separation: outer message describes the failure class,
cause carries the diagnostic detail.
SgtPooki added a commit that referenced this pull request Apr 28, 2026
…lureReason

Companion to #490, which now carries the actual failure detail via
Error.cause rather than concatenating it into the outer message.
Promote cause.message to the top-level failureReason field when
present, falling back to error.message when no cause is attached
(e.g. for non-rethrown errors thrown directly inside the catch block).

Result: { failureReason: "IPNI verification timed out after 60000ms" }
instead of { failureReason: "IPNI verification failed for deal X:
root CID not verified" }.
@SgtPooki SgtPooki self-assigned this Apr 28, 2026
@SgtPooki SgtPooki moved this from 📌 Triage to 🔎 Awaiting review in FOC Apr 28, 2026
@github-project-automation github-project-automation Bot moved this from 🔎 Awaiting review to ✔️ Approved by reviewer in FOC Apr 28, 2026
@SgtPooki SgtPooki merged commit fe53f35 into main Apr 28, 2026
8 of 13 checks passed
@SgtPooki SgtPooki deleted the fix/ipni-failure-reason-in-rethrow branch April 28, 2026 20:35
@github-project-automation github-project-automation Bot moved this from ✔️ Approved by reviewer to 🎉 Done in FOC Apr 28, 2026
SgtPooki added a commit that referenced this pull request May 4, 2026
…failed (#491)

* feat(ipni): expose failureReason as top-level field on ipni_tracking_failed

toStructuredError(error) only captures error.message inside a nested
error.message field, which forces BS users to JSON-extract through two
layers to filter or aggregate by failure type. Promote the underlying
message to a top-level failureReason field so operators and SPs can
group ipni_tracking_failed events by reason class without parsing the
stack-bearing error blob.

Companion to the fix in #490.

* refactor(ipni): prefer error.cause.message over error.message for failureReason

Companion to #490, which now carries the actual failure detail via
Error.cause rather than concatenating it into the outer message.
Promote cause.message to the top-level failureReason field when
present, falling back to error.message when no cause is attached
(e.g. for non-rethrown errors thrown directly inside the catch block).

Result: { failureReason: "IPNI verification timed out after 60000ms" }
instead of { failureReason: "IPNI verification failed for deal X:
root CID not verified" }.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🎉 Done

Development

Successfully merging this pull request may close these issues.

IPNI xxx root CID not verified

4 participants