Skip to content

fix(backtest): a 202 on the execute poll no longer yields an empty result - #3

Merged
mrmx merged 1 commit into
mainfrom
fix/keep-polling-on-202
Jul 27, 2026
Merged

fix(backtest): a 202 on the execute poll no longer yields an empty result#3
mrmx merged 1 commit into
mainfrom
fix/keep-polling-on-202

Conversation

@mrmx

@mrmx mrmx commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

What

Reads the execute-result status through a null-safe accessor, so a 202 continues the poll instead of ending it.

Why

The API answers 202 with an empty body when a job is known but its result is not readable yet, so a successful response can legitimately carry no state. BacktestWorkflow dereferenced getState() inside the retry predicate.

The failure is quiet, which is what makes it worth a regression test. The NullPointerException is raised inside Failsafe's result predicate and swallowed there: the retry simply does not match, the poll ends, and the caller is handed a null ResultMap for a backtest that actually completed — the same "finished, and I could not find it" trap the 202 exists to prevent, moved to the client side.

Changes

  • statusOf(BacktestJobResult) returns the status or null; StatusNormalizer already maps null to IN_PROGRESS, so the loop asks again under its existing timeout.
  • Used by the retry predicate, the post-loop classification and the result log.
  • A test drives two 202s (empty body, no state) before the real result.

Validation

Full suite green (49 tests). Verified fail-first: reverting the guard fails the new test — and it fails with a null result rather than a visible NPE, which is exactly the point.

…sult

The API answers 202 with an empty body when a job is known but its result is
not readable yet, so a successful response can legitimately carry no state.
BacktestWorkflow dereferenced getState() inside the retry predicate.

The failure is quiet, which is what makes it worth a regression test. The
NullPointerException is raised inside Failsafe's result predicate and swallowed
there: the retry does not match, the poll ends, and the caller is handed a null
ResultMap for a backtest that actually completed -- the same "finished, and I
could not find it" trap the 202 exists to prevent, moved to the client side.

The status is now read through a null-safe accessor, so an absent state
normalizes to IN_PROGRESS and the loop asks again under its existing timeout.
Verified fail-first: reverting the guard fails the new test with a null result,
not with a visible NPE.
@mrmx
mrmx temporarily deployed to Preproduction July 26, 2026 21:54 — with GitHub Actions Inactive
@mrmx
mrmx merged commit cdccbd3 into main Jul 27, 2026
5 checks passed
@mrmx
mrmx deleted the fix/keep-polling-on-202 branch July 27, 2026 09:27
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.

1 participant