Skip to content

feat(call): emit explicit final run status and JSON output (#1139)#1198

Open
l2ysho wants to merge 3 commits into
masterfrom
1139-improve-apify-call-and-task-run-final-status-and-json-output-for-agents
Open

feat(call): emit explicit final run status and JSON output (#1139)#1198
l2ysho wants to merge 3 commits into
masterfrom
1139-improve-apify-call-and-task-run-final-status-and-json-output-for-agents

Conversation

@l2ysho

@l2ysho l2ysho commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Closes #1139

apify call and apify task run started a cloud run and streamed logs, but
gave no explicit final result — a run could start successfully yet finish
FAILED, TIMED_OUT, or ABORTED with no clear signal. Agents and CI could not
tell "run started" from "run succeeded".

Add a shared run-result module that owns the final-status contract:

  • getRunExitCode maps terminal status to a process exit code (SUCCEEDED→0,
    ABORTED→3, TIMED-OUT→2, FAILED→the Actor's own exit code or 1).
  • buildRunResultJson produces the structured --json payload (ok, operation,
    actor, run.status, run.exitCode, storage, error.logTail, exitCode).
  • printRunResultSummary prints a human-readable final summary, including a
    Reason block with the last log lines on failure.
  • finalizeRun is the single entry point both commands funnel through.

apify task run now waits for the run to finish, gains --json, and reports a
status-derived exit code. Final-status presentation and exit-code handling move
out of runActorOrTaskOnCloud into the commands. Failed, timed-out, and aborted
runs now exit non-zero.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

`apify call` and `apify task run` started a cloud run and streamed logs, but
gave no explicit final result — a run could start successfully yet finish
FAILED, TIMED_OUT, or ABORTED with no clear signal. Agents and CI could not
tell "run started" from "run succeeded".

Add a shared `run-result` module that owns the final-status contract:
- `getRunExitCode` maps terminal status to a process exit code (SUCCEEDED→0,
  ABORTED→3, TIMED-OUT→2, FAILED→the Actor's own exit code or 1).
- `buildRunResultJson` produces the structured `--json` payload (ok, operation,
  actor, run.status, run.exitCode, storage, error.logTail, exitCode).
- `printRunResultSummary` prints a human-readable final summary, including a
  Reason block with the last log lines on failure.
- `finalizeRun` is the single entry point both commands funnel through.

`apify task run` now waits for the run to finish, gains `--json`, and reports a
status-derived exit code. Final-status presentation and exit-code handling move
out of `runActorOrTaskOnCloud` into the commands. Failed, timed-out, and aborted
runs now exit non-zero.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added this to the 143rd sprint - Tooling team milestone Jun 15, 2026
@github-actions github-actions Bot added t-tooling Issues with this label are in the ownership of the tooling team. tested Temporary label used only programatically for some analytics. labels Jun 15, 2026
The final-status contract nests the run status under `run.status` and adds
`ok`/`operation`/`exitCode`; update the runs lifecycle e2e to match instead of
reading the old top-level `status`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@l2ysho l2ysho added t-dx Issues owned by the DX team. and removed t-tooling Issues with this label are in the ownership of the tooling team. labels Jun 15, 2026
@l2ysho l2ysho marked this pull request as ready for review June 22, 2026 11:30
run: {
id: run.id,
status: run.status,
exitCode: run.exitCode ?? null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Q: do we need inner exitCode with the top one in place (exitCode: getRunExitCode(run))?

datasetUrl: datasetUrl(run.defaultDatasetId),
},
error: ok
? null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: let's use the same format as in case of #1199, meaning, the error should be undefined if ok===true.

https://github.com/apify/apify-cli/pull/1199/changes#diff-0d7599d95e0dc9a17793baf7a7728bc78a4c6495e472e59a400a771d16c758adR62

return;
}

if (!silent) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: the silent should silence the json output as well, right?
Now if both silent and json are set, the json output still prints.

@DaveHanns DaveHanns left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pre-approving. The silent vs json should be definitely addressed before merging.

Comment thread docs/reference.md
FLAGS
-b, --build=<value> Tag or number of the build to run
(e.g. "latest" or "1.2.34").
--json Format the command output as JSON

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Needs a period at the end :D

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

Labels

t-dx Issues owned by the DX team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve apify call and task run final status and JSON output for agents

4 participants