Skip to content

edge3: Exit non-zero when worker admin CLI commands fail - #70112

Merged
dheerajturaga merged 1 commit into
apache:mainfrom
dkranchii:fix-edge3-worker-admin-exit-codes
Jul 26, 2026
Merged

edge3: Exit non-zero when worker admin CLI commands fail#70112
dheerajturaga merged 1 commit into
apache:mainfrom
dkranchii:fix-edge3-worker-admin-exit-codes

Conversation

@dkranchii

Copy link
Copy Markdown
Contributor

add-worker-queues, remove-worker-queues, and set-worker-concurrency raised bare SystemExit after catching a TypeError from the model layer (raised when the target worker is in OFFLINE, OFFLINE_MAINTENANCE, or UNKNOWN state). SystemExit() with no argument yields exit code 0, so shell scripts wrapping these commands saw success and continued as if the queue or concurrency change had been applied, when in fact it had been silently rejected.

Pass the exception message to SystemExit(str(e)) so the process exits with status 1 and writes the failure to stderr. Matches this file's own convention for validation-error paths (e.g. raise SystemExit("Error: No queues specified to add.") a few lines above each fix site) and the raise SystemExit(str(e)) pattern already used in providers/edge3/src/airflow/providers/edge3/cli/worker.py.

The model layer at providers/edge3/src/airflow/providers/edge3/models/edge_worker.py already calls logger.error(error_message) before raising, so the CLI-side logger.error(str(e)) was strictly duplicative and is removed.

Adds parametrized tests over all three subcommands asserting that SystemExit.code carries the error message (i.e. exit status is 1, not 0).


Was generative AI tooling used to co-author this PR?
  • Yes — Cursor

@boring-cyborg boring-cyborg Bot added area:providers provider:edge Edge Executor / Worker (AIP-69) / edge3 labels Jul 20, 2026
@dkranchii
dkranchii force-pushed the fix-edge3-worker-admin-exit-codes branch from 20d94d1 to 244b190 Compare July 24, 2026 17:33
@dkranchii

dkranchii commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@jscheffl @dheerajturaga can you review this.

@dheerajturaga

Copy link
Copy Markdown
Member

Thanks for tackling this — the exit-code bug is real and the motivation is spot on. I reviewed the change and have one blocker plus a couple of suggestions.

The production fix is correct. Switching the three except TypeError handlers from bare raise SystemExit (exit code 0) to raise SystemExit(str(e)) (exit 1 + message on stderr) is the right call. The model layer already logs the error before raising, so dropping the CLI-side logger.error(str(e)) is a clean de-dup, and raise SystemExit(str(e)) matches the existing convention in cli/worker.py. (Omitting from e is fine here — B904 isn't in the repo's ruff config, and the worker.py sites omit it too.)

🔴 Blocker — the new test fails. The test builds args with types.SimpleNamespace, but these commands are wrapped by @cli_utils.action_cli, whose _check_cli_args (airflow-core/src/airflow/utils/cli.py:56) rejects anything that isn't an argparse.Namespace:

ValueError: 1st positional argument should be argparse.Namespace instance, but is <class 'types.SimpleNamespace'>

That ValueError escapes before any SystemExit, so pytest.raises(SystemExit) never matches and all three cases error out — which is what the red Non-DB tests: providers … edge3 and Provider distributions tests jobs are reporting. Swapping SimpleNamespaceargparse.Namespace (same fields) makes all three pass, and the test then correctly fails without the production change.

🟡 Suggestion — two identical bug sites remain. The same bare-raise SystemExit-after-except TypeError pattern is still present at edge_command.py:329-330 (remote_worker_update_maintenance_comment) and :344-345 (remove_remote_worker); their model functions (change_maintenance_comment, remove_worker) log-and-raise TypeError just like the three you fixed. Folding these two into this PR (and into the parametrized test) would make the fix complete rather than partial.

Minor — test comment. The comment says it checks "exit code 1," but the assertion checks that .code equals the message string; the exit-status-1 behavior happens later when the interpreter prints a non-int code. Might reword to avoid conflating the two.


Drafted-by: Claude Code (Opus 4.8); reviewed by @dheerajturaga before posting

@dkranchii
dkranchii force-pushed the fix-edge3-worker-admin-exit-codes branch from 244b190 to feb57e4 Compare July 25, 2026 22:18
The add-worker-queues, remove-worker-queues, set-worker-concurrency,
update-maintenance-comments, and remove-worker subcommands raised bare
`SystemExit` after catching a TypeError from the model layer, which
yields exit status 0. Shell scripts wrapping these commands treated
failures as success and continued as if the queue, concurrency,
maintenance-comment, or worker-removal change had been applied.
Pass the exception message to SystemExit so the process exits with
status 1 and writes the failure to stderr, matching the file's own
convention for validation-error paths (see the explicit
`raise SystemExit("Error: ...")` calls in the same subcommands) and the
`raise SystemExit(str(e))` pattern already used elsewhere in the edge3
CLI. The model layer already logs the error before raising, so the
redundant logger.error call in the three subcommands that had one is
removed.
@dkranchii
dkranchii force-pushed the fix-edge3-worker-admin-exit-codes branch from feb57e4 to 862f168 Compare July 25, 2026 22:54
@dkranchii

Copy link
Copy Markdown
Contributor Author

@dheerajturaga updated the pr based on your suggestion.

@dheerajturaga dheerajturaga left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome! thanks for fixing this

@dheerajturaga
dheerajturaga merged commit 283d5c3 into apache:main Jul 26, 2026
79 checks passed
Kunal8954 pushed a commit to Kunal8954/airflow that referenced this pull request Jul 27, 2026
The add-worker-queues, remove-worker-queues, set-worker-concurrency,
update-maintenance-comments, and remove-worker subcommands raised bare
`SystemExit` after catching a TypeError from the model layer, which
yields exit status 0. Shell scripts wrapping these commands treated
failures as success and continued as if the queue, concurrency,
maintenance-comment, or worker-removal change had been applied.
Pass the exception message to SystemExit so the process exits with
status 1 and writes the failure to stderr, matching the file's own
convention for validation-error paths (see the explicit
`raise SystemExit("Error: ...")` calls in the same subcommands) and the
`raise SystemExit(str(e))` pattern already used elsewhere in the edge3
CLI. The model layer already logs the error before raising, so the
redundant logger.error call in the three subcommands that had one is
removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providers provider:edge Edge Executor / Worker (AIP-69) / edge3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants