Skip to content

FE-1222: Classify Petrinaut optimization transport errors in the UI#9063

Draft
kube wants to merge 3 commits into
mainfrom
cf/fe-1222-classify-petrinaut-optimization-transport-errors
Draft

FE-1222: Classify Petrinaut optimization transport errors in the UI#9063
kube wants to merge 3 commits into
mainfrom
cf/fe-1222-classify-petrinaut-optimization-transport-errors

Conversation

@kube

@kube kube commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

🌟 What is the purpose of this PR?

When a long optimization stream is reset mid-run, the UI shows the raw network error — the caught fetch/reader.read() exception message forwarded verbatim. This replaces it with a classified, actionable error and threads NodeAPI's correlation ids to the UI, so a failed run is traceable to the NodeAPI and optimizer logs and the user gets a clear next step. Already-received trials are preserved and a Retry action is offered.

🔗 Related links

  • FE-1222 — this issue
  • FE-1217 — parent hardening issue
  • SRE-831 — the suspected root cause (proxy/LB streaming timeout); this PR improves the experience regardless of it

🚫 Blocked by

🔍 What does this change?

  • messages.ts: optimizationResponseStart carries the x-hash-request-id / X-Optimization-Run-ID response headers; optimizationError gains a category (network / http / protocol / aborted) plus optional correlation ids, httpStatus, and errorName.
  • Host (process-editor.tsx): captures the correlation headers, forwards them on response-start, and classifies its own transport failures as network with a safe message (no raw exception text).
  • Bridge (create-bridge-petrinaut-optimization.ts): a new PetrinautOptimizationTransportError carries the structured fields; non-ok responses are classified http (with status + correlation ids), protocol violations protocol, and the response-start timeout network; correlation ids captured at response-start backfill a later stream error.
  • Provider (provider.tsx): builds a safe, progress-aware message ("Connection to the optimization service was interrupted after N of M trials. Retry the optimization. (diagnostic id: …)"), keeps the received trials, stores errorCategory / errorDiagnostics on the record, and adds retryOptimization to start a fresh run from the failed one's input. The error type crosses the app→lib boundary, so it is duck-typed rather than matched with instanceof.
  • View drawer: a Retry action on a failed run.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • require changes to docs which are made as part of this PR

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

🛡 What tests cover this?

  • create-bridge-petrinaut-optimization.test.ts: protocol classification (no-terminal, data-after-terminal) and the HTTP path carrying status + correlation ids.
  • create-bridge-petrinaut-optimization.browser.test.ts: a mid-stream host error is reclassified and backfilled with the response-start correlation ids.
  • provider.test.tsx: a classified transport failure yields the composed message + preserved trials + errorCategory/errorDiagnostics; retryOptimization starts a fresh run from the original input.
  • messages.test.ts, create-optimization-drawer.test.tsx: kept green with the extended message and context shapes.

All four suites pass (@hashintel/petrinaut react + UI optimization tests; @apps/hash-frontend bridge + messages tests).

❓ How to test this?

  1. Check out the branch / open the deployment.
  2. Start a long optimization and interrupt the connection (or let a proxy reset it) so the stream drops mid-run.
  3. Confirm the result drawer shows a classified message with the trial progress and a diagnostic id, the already-received trials remain listed, and a Retry button starts a fresh run.

🤖 Generated with Claude Code

kube and others added 3 commits July 19, 2026 01:52
Replace the raw `network error` the host forwarded from a caught
fetch/reader exception with a classified, actionable error, and thread the
NodeAPI correlation ids to the UI so a failed run is traceable to the
NodeAPI and optimizer logs.

- messages: optimizationResponseStart carries the x-hash-request-id /
  X-Optimization-Run-ID response headers; optimizationError gains a
  category (network/http/protocol/aborted) plus optional correlation ids,
  http status, and error name.
- host (process-editor): captures the correlation headers, forwards them,
  and classifies its own transport failures as `network` with a safe
  message.
- bridge: a PetrinautOptimizationTransportError carries the structured
  fields; HTTP (non-ok) failures are classified `http` with status +
  correlation ids, protocol violations `protocol`, and the response-start
  timeout `network`; correlation ids captured at response-start backfill a
  later stream error.
- provider: builds a safe, progress-aware message ("...interrupted after N
  of M trials. Retry the optimization. (diagnostic id: ...)"), keeps the
  received trials, stores the category/diagnostics on the record, and adds
  retryOptimization to start a fresh run from the failed one's input.
- view drawer: a Retry action on a failed run.

Tests cover network/http/protocol classification, correlation-id
threading through the bridge, the composed message + preserved trials, and
retry.
@kube kube self-assigned this Jul 19, 2026
@vercel

vercel Bot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Jul 19, 2026 4:36pm
petrinaut Ready Ready Preview, Comment Jul 19, 2026 4:36pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Jul 19, 2026 4:36pm

@github-actions github-actions Bot added area/apps > hash* Affects HASH (a `hash-*` app) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/apps labels Jul 19, 2026
@semgrep-code-hashintel

Copy link
Copy Markdown

Semgrep found 1 insufficient-postmessage-origin-validation finding:

  • apps/hash-frontend/src/pages/processes/[uuid]/embed.page/create-bridge-petrinaut-optimization.ts

No validation of origin is done by the addEventListener API. It may be possible to exploit this flaw to perform Cross Origin attacks such as Cross-Site Scripting(XSS).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash* Affects HASH (a `hash-*` app) area/apps area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants