client: add timeout exit code for wait polling (PRINFRA-125)#46
Merged
Merged
Conversation
PRINFRA-125 CLI M1: Pagination, polling + HTTP hardening
Implement the framework features that make generated commands production-ready: pagination, polling, and HTTP client hardening. ScopePagination
Polling
HTTP Client Hardening
Not in scope (moved to PRINFRA-139)
Acceptance Criteria
|
Collaborator
Author
Merge activity
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
Poll timeouts (
--waitexceeding--timeout) now return exit code 4 instead of exit code 1, distinguishing "resource created but not yet complete" from "operation failed." This was prompted by dogfood feedback where a user resubmitted a video create because the timeout error gave no indication the resource already existed — wasting a credit.Three changes:
Exit code 4 (
ExitTimeout) — new exit code meaning "the side-effect happened but completion wasn't confirmed." The agent reads exit 4 and knows not to retry create; instead it polls manually with the hintedgetcommand. Exit 1 remains "failure or unknown" — retry is not always safe (transport failure after server processes create leaves the outcome ambiguous).Partial result on stdout — on timeout, the last polled status response is emitted to stdout (same shape as a successful
video get). The agent gets the resource ID, current status, and any other fields without parsing stderr. Builder uses"data", nil(key-value rendering in--human, matching the success path).HintCommandonPollConfig— timeout hints are explicit per poll config, not inferred fromspec.Group. This matters forvideo-agent create, which polls/v3/videos/{video_id}— the correct hint isheygen video get <id>, notheygen video-agent get <id>(which doesn't exist).Cancel vs timeout distinction preserved:
classifyPollContextErrorcheckscontext.DeadlineExceeded(→ErrPollTimeout, exit 4) vscontext.Canceled(→CLIError{Code: "canceled"}, exit 1). Ctrl-C produces no partial result and no special exit code.Error handling flow:
translateCreateContextError→ exit 1. The CLI can't confirm whether the resource exists.classifyPollContextError→ErrPollTimeout→ builder outputs partial result + exit 4.classifyPollContextError→CLIError→ exit 1, no partial result.ErrPollFailedpath unchanged → exit 1 with failure response on stdout.Linear: PRINFRA-125
Testing
TestExecuteAndPoll_TimeoutWhileWaiting— verifyErrPollTimeoutwith ResourceID and last status DataTestExecuteAndPoll_TimeoutDuringRequest— timeout before first poll, Data is nil, ResourceID still populatedTestExecuteAndPoll_Cancel— cancel returnsCLIError{Code: "canceled", ExitCode: ExitGeneral}, notErrPollTimeoutTestGenBuilder_VideoCreate_Wait_Timeout— exit 4, partial result on stdout, hint in stderrTestGenBuilder_VideoCreate_Wait_TimeoutBeforeFirstPoll— exit 4, empty stdoutTestGenBuilder_VideoCreate_Wait_Timeout_Human— human mode renders partial result as key-valueTestGenBuilder_VideoAgentCreate_Wait_Timeout_UsesVideoGetHint— hint says "video get", not "video-agent get"TestGeneratedRoot_RootHelp_ListsTimeoutExitCode— root--helpincludes exit code 4