Skip to content

fix: show clear error and non-zero exit on non-JSON API responses#27

Open
ektasawant wants to merge 3 commits into
mainfrom
fix/ekta/ava-non-json-error-CMP-44313
Open

fix: show clear error and non-zero exit on non-JSON API responses#27
ektasawant wants to merge 3 commits into
mainfrom
fix/ekta/ava-non-json-error-CMP-44313

Conversation

@ektasawant

@ektasawant ektasawant commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Make dci fail cleanly when the DoiT API returns a non-successful AVA askSync
response instead of dumping raw HTML and exiting 0.

Relates to CMP-46498 (epic CMP-44313).

Background

dci wraps restish, which on a non-JSON body silently falls back to printing the
raw bytes and derives its exit code purely from the HTTP status. Two AVA failure
modes slip through as a result:

  • An upstream timeout/maintenance surfaces the Cloudflare edge's HTML page
    (e.g. a 524 rendered as the DoiT maintenance page) — dumped as a wall of HTML.
  • Once askSync has started streaming, a mid-generation failure returns an
    application error body under a locked 2xx status, which restish treats as
    success (exit 0).

Changes

Adds a dciResponseGuard that wraps restish's response formatter:

  • Non-JSON / HTML pages → prints a clear, actionable message (likely upstream
    timeout/maintenance, HTTP status, trace id, retry/contact support) and exits
    non-zero. Trace id is read from Cf-Ray, X-Doit-Trace, X-Request-Id,
    X-Cloud-Trace-Context, or Traceparent.
  • 2xx with a top-level JSON error → still prints the structured error body
    (respecting --output), then frames it as an error on stderr and forces a
    non-zero exit.
  • JSON success and SSE streaming pass through to restish untouched.

Scope note

The formatter seam has no access to the request URL, so the JSON-error check is
global rather than AVA-only. It's intentionally conservative — it fires only on a
2xx body whose top-level error is a non-empty string/object, which isn't a valid
success shape for any DCI endpoint.

Test plan

  • go build ./... && go vet ./... && go test ./...
  • Unit tests: HTML detection (content-type + body sniff + bytes), trace-id
    extraction/priority, jsonApplicationError cases, and guard behavior
    (HTML swallowed + flagged; 2xx-error body printed + flagged; JSON/SSE
    delegate untouched).
  • Manual: point at an env returning the maintenance HTML → clear message +
    non-zero exit; confirm a normal query and ask-ava-streaming are unaffected.

@ektasawant ektasawant requested a review from apgiorgi as a code owner July 7, 2026 15:09
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@ektasawant ektasawant marked this pull request as draft July 7, 2026 15:09
Comment thread main.go
Comment thread main.go

@apgiorgi apgiorgi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed and verified the guard against the OpenAPI spec (doit-api.yaml): the AVA askSync top-level error-under-200 shape is confirmed, and the conservative top-level-object scoping correctly avoids false-positives on the only other 2xx-with-error endpoint (/insights/v1/results, a top-level array). Build/vet/tests pass, all CI green. LGTM.

@apgiorgi apgiorgi marked this pull request as ready for review July 7, 2026 15:57
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@ektasawant ektasawant marked this pull request as draft July 7, 2026 19:05
@ektasawant

Copy link
Copy Markdown
Collaborator Author

@apgiorgi , could you please review again?

@ektasawant ektasawant marked this pull request as ready for review July 8, 2026 08:31
@ektasawant ektasawant requested a review from apgiorgi July 8, 2026 08:32
@apgiorgi

apgiorgi commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

👋 @ektasawant — this is approved and CI is green, but the merge is blocked by a repo constraint rather than anything in the code.

This repo only allows rebase-merge (squash and merge-commits are disabled), and GitHub refuses to rebase a branch that contains a merge commit. This branch has one — ab432251 Merge branch 'main' ... — so the merge button errors with "This branch can't be rebased."

Easiest fix is to linearize your branch by rebasing onto main (instead of merging main in), which drops that merge commit:

git checkout fix/ekta/ava-non-json-error-CMP-44313
git fetch origin
git rebase origin/main
# If a conflict pops up it's the trivial one in main.go around installResponseGuard() /
# registerAgentFlags() ordering — keep installResponseGuard() first, then continue:
#   git add main.go && git rebase --continue
git push --force-with-lease

After that the history is just your two real commits on top of main, and rebase-merge will go through. No content changes needed — this only removes the merge commit. Ping me if the conflict is anything more than the ordering above and I'll help.

@ektasawant ektasawant force-pushed the fix/ekta/ava-non-json-error-CMP-44313 branch from c3e3529 to 54b833e Compare July 9, 2026 06:58
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants