Skip to content

cli: Add program error diagnostics command#6510

Open
Dnreikronos wants to merge 3 commits into
feldera:mainfrom
Dnreikronos:cli/program_errors
Open

cli: Add program error diagnostics command#6510
Dnreikronos wants to merge 3 commits into
feldera:mainfrom
Dnreikronos:cli/program_errors

Conversation

@Dnreikronos

@Dnreikronos Dnreikronos commented Jun 20, 2026

Copy link
Copy Markdown

fixes #5738

imo this is the smallest useful fix here. fda logs only reads runtime logs, so users had to dig through the full pipeline json to find compilation diagnostics.

adds fda program errors for program_error, with text output for sql messages, rust compiler output, and system errors. --format json returns the raw error payload. lgtm to keep this separate from logs for now since idk if we want to mix runtime logs and compiler output in one command. i also added parser and formatter tests.

@mihaibudiu mihaibudiu requested a review from gz June 20, 2026 00:08
Comment thread crates/fda/src/main.rs
output,
"SQL compiler exit code: 1\n\
warning: PRIMARY KEY cannot be nullable: PRIMARY KEY column 'C' has type INTEGER, which is nullable (line 2, column 4)\n\
2| c INT PRIMARY KEY\n\

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.

I wonder whether we need a "verbosity" argument which would enable the snippet being shown

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

fixed the ci fmt issue in e0a907d. on the snippet bit, i'd keep snippets in text output for now. personally, i think hiding them would make this cmd less useful, since the whole point is to avoid digging through the full pipeline json just to understand a compiler error. json still gives the raw payload for ppl/scripts that want to handle it differently. if output ends up too noisy, i'd rather add a specific --no-snippets or --summary flag later than introduce a new verbosity arg just for this cmd.

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.

"Verbosity" would be a new fda flag, which applies to all other fda commands. But that's a separate issue we should file and solve.

@mihaibudiu

Copy link
Copy Markdown
Contributor

Our pre-merge checks don't check much, but they didn't like the formatting of your Rust

@gz gz 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.

it would be good to exercise this as part of test.bash integration test as well

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approve. Small, focused, well-tested addition that closes a real gap — fda logs only surfaces runtime output, so users currently have to spelunk through the pipeline JSON for SQL/Rust diagnostics. Splitting this into a dedicated program errors subcommand is the right call.

format_program_errors is straightforward and the four unit tests (empty, SQL with snippet, Rust stdout+stderr, system error) cover every branch including the warning vs. error severity flip and the trailing-newline normalisation. Good shape: pure function over &ProgramError, easy to extend if more fields land.

Two non-blocking notes:

  1. crates/fda/src/main.rsErrors arm: if program_error is None the command exits 1 with "did not include program errors". That's the safe choice for a pre-UPGRADE_NOTICE server, but for a current server a fully-compiled pipeline can legitimately return program_error: None (no diagnostics to report). Consider treating None the same as format_program_errors does for an empty struct ("No compilation errors or warnings.\n", exit 0). Otherwise scripting fda program errors X && deploy will spuriously fail.

  2. format_program_errors: severity is a &str chosen from if message.warning { "warning" } else { "error" }. Worth a quick sanity check that sql.exit_code == 0 and all messages flagged warning: true is a valid state — if so, the header "SQL compiler exit code: 0" followed by a "warning:" line reads cleanly, which is what you want.

Nit: the snippet branch prints snippet directly with push_str; if a snippet ever contains a stray { it's still safe because you're not running it through format!. Good.

@Dnreikronos

Copy link
Copy Markdown
Author

it would be good to exercise this as part of test.bash integration test as well

added this in 31bf0f6. test.bash now creates a bad sql pipeline, waits for sql_error, then exercises both text and json output from fda program errors.

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-APPROVE on f586b8831bf0f6.

Apply formatter to program error snippets collapses the nested if let Some(snippet) = &message.snippet { if !snippet.is_empty() { … } } into a let-chain — pure 2024-edition formatting cleanup, semantics identical.

Test program error diagnostics in fda script adds the integration coverage that was missing from the earlier rounds: creates pbad with an intentionally-invalid SELECT invalid, polls fda program status pbad for up to 60s waiting for the SqlError to surface, then exercises both human and JSON output paths of fda program errors. The 60-second cap is consistent with the rest of the script's pattern, the JSON assertion uses jq -e so a zero-length messages array exits non-zero (test fails loudly), and the cleanup path adds fda delete --force pbad to the top-of-script cleanup block as well — no leak risk on re-run. Nice.

No blockers; APPROVE stands.

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-APPROVE on 31bf0f6a4e. Two new commits since prior approval at f586b882e0:

  1. e0a907df9b — formatter pass folding the nested if let Some(snippet) = ... { if !snippet.is_empty() { ... } } into a let-chain. Matches the rustfmt complaint Mihai flagged.
  2. 31bf0f6a4e — adds an integration leg to test.bash per Mihai's ask: creates pbad with SELECT invalid, polls up to 60s for SqlError, then exercises both the text formatter (fda program errors pbad | grep -i "error:") and the JSON path (fda --format json program errors pbad | jq -e '.sql_compilation.messages | length > 0'). Cleanup at the top + bottom of test.bash properly removes pbad and bad-program.sql so reruns stay idempotent.

Two small nits, non-blocking:

  • The poll uses grep -q "SqlError" against fda program status, then immediately re-runs fda program status pbad | grep "SqlError" as an assertion. The second invocation is functionally the same as breaking out of the loop having seen it once; you can drop it. As written, if the 60s window expires and status flips to RustError between the two reads, the loop exits via the for end (no break) and the assert fails for a different reason. Cleaner: add an explicit else echo "timeout"; exit 1 after the loop body.
  • jq -e '.sql_compilation.messages | length > 0' is a good shape check but doesn't pin that error_type / message strings are non-empty. A follow-up could assert (.sql_compilation.messages[0].message | length) > 0 to catch a regression where the body is dropped but the array remains.

Nice follow-through on the maintainer feedback. Good to merge once CI is green.

@Dnreikronos Dnreikronos requested a review from gz June 20, 2026 18:45
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.

[cli] fda cannot retrieve compilation errors and warnings

4 participants