Structured JSON error envelope + status propagation to scripts/pipe #6578
Structured JSON error envelope + status propagation to scripts/pipe #6578notxvilka wants to merge 4 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files
... and 8 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
e9101a2 to
0bd1e7d
Compare
0bd1e7d to
d5656e6
Compare
d5656e6 to
08eef46
Compare
08eef46 to
4d6ff66
Compare
* Add the `rz_cmd_status_tostring` API that maps an `RzCmdStatus` to a stable, machine-readable string (`OK`, `WRONG_ARGS`, `ERROR`, `INVALID`, `NONEXISTINGCMD`, `EXIT`). * Record the status of every executed command in a new `RzCore.last_cmd_status` field, so consumers driving Rizin can read back whether the command that just ran succeeded or failed. Co-authored-by agent: Claude/claude-opus-4-8
* Turn the root `_` (last output) command into a "Last command introspection" group and add a `_s`/`_sj` subcommand that prints the status of the previously executed command from `RzCore.last_cmd_status`. * `_s` prints the stable status code while `_sj` reports it as a JSON object together with the integer code from `rz_cmd_status2int`, so an agent driving Rizin over rzpipe can query success or failure explicitly. Co-authored-by agent: Claude/claude-opus-4-8
When a command is invoked in a JSON output mode and the `cfg.json.status`
config is enabled, emit a machine-readable status object on stdout after
the command's own output, so a consumer driving Rizin over rzpipe or
`rizin -c` can reliably tell success from failure (and a failure from an
empty-but-successful result). The envelope is reported consistently for
every command, so the trailing object is always present and only its
`error` field changes: `{"error":null}` on success and
`{"error":{"code":"WRONG_ARGS","message":"...","command":"afl"}}` on
failure.
* Gate the behavior behind the new `cfg.json.status` config (default
`false`). Reporting the envelope for every JSON command changes their
output, so keeping it opt-in preserves the current behavior while
letting agents enable structured status reporting.
* The error object reuses `rz_cmd_status_tostring` for the stable `code`
and reports the canonical command name without the mode suffix.
Co-authored-by agent: Claude/claude-opus-4-8
Optionally make `rizin -q`/`-c`/`-i` exit with a non-zero process code when a command fails, so that shells and CI can detect errors instead of always seeing a successful exit. * Gate the behavior behind the new `cfg.exit.errorcode` config (default `false`) to preserve the historical behavior of always exiting with 0 in batch mode. * `run_commands` now reports whether any executed command returned a failing status (non-OK and non-EXIT); the process exit code is set to 1 from that result only when the config is enabled. A `q`/quit request is treated as success. Co-authored-by agent: Claude/claude-opus-4-8
4d6ff66 to
3166169
Compare
Rot127
left a comment
There was a problem hiding this comment.
Just those nitpicks I found on a second look.
| pj_ko(pj, "error"); | ||
| pj_ks(pj, "code", rz_cmd_status_tostring(status)); | ||
| pj_ks(pj, "message", cmd_status_message(status)); | ||
| pj_ks(pj, "command", cmd_name); |
There was a problem hiding this comment.
Also adding the arguments here would be helpful. Because one of the errors is "wring arguments".
| core->vmode = false; | ||
| core->lastcmd = NULL; | ||
| core->cmdlog = NULL; | ||
| core->last_cmd_status = RZ_CMD_STATUS_OK; |
There was a problem hiding this comment.
| core->last_cmd_status = RZ_CMD_STATUS_OK; | |
| core->last_cmd_status = RZ_CMD_STATUS_INVALID; |
Or not? Because there was no command which ran before. So it is not in a valid state.
| } | ||
| if (ret < 0 || (ret == 0 && quiet)) { | ||
| rz_cons_flush(); | ||
| return false; |
There was a problem hiding this comment.
had_error is not updated here and above
| NAME=batch exit code zero on successful command | ||
| FILE== | ||
| ARGS=-e cfg.exit.errorcode=true | ||
| CMDS=s 0 | ||
| EXPECT= | ||
| RUN | ||
|
|
||
| NAME=batch exit code zero on quit | ||
| FILE== | ||
| ARGS=-e cfg.exit.errorcode=true | ||
| CMDS=q | ||
| EXPECT= | ||
| RUN |
There was a problem hiding this comment.
Better make EXIT_STATUS=0 explicit
Your checklist for this pull request
RZ_APIfunction and struct this PR changes.RZ_API).Detailed description
Largely mechanistic change of adding an envelope and optionally reporting status for JSON commands, covering the A1 of the "AI issue" - machine detectable errors: #6543
Test plan
Ci is green
Closing issues
Partially addresses #6543