mattfaltyn opened a new issue, #5097: URL: https://github.com/apache/polaris/issues/5097
### Describe the bug `polaris setup apply` catches and logs provisioning exceptions inside its entity-processing helpers, but does not propagate or aggregate them. After processing, it unconditionally logs: ```text === Setup Apply Process Completed Successfully === ``` Because no exception reaches the CLI entrypoint, the process exits with status 0 even when one or more requested principals, roles, grants, catalogs, namespaces, or policies were not created. This makes the setup command unsafe to rely on from CI or deployment automation: a partially configured environment is reported as successful. Relevant code on current `main` (`7f0528705a2ab08ed4857be3e4046cecdd7b384c`): - [`SetupCommand.execute`](https://github.com/apache/polaris/blob/7f0528705a2ab08ed4857be3e4046cecdd7b384c/client/python/apache_polaris/cli/command/setup.py#L524-L578) unconditionally logs successful completion. - [`_create_principal_roles`](https://github.com/apache/polaris/blob/7f0528705a2ab08ed4857be3e4046cecdd7b384c/client/python/apache_polaris/cli/command/setup.py#L689-L726) catches exceptions and returns normally; the same pattern exists in the other setup helpers. - [The CLI entrypoint](https://github.com/apache/polaris/blob/7f0528705a2ab08ed4857be3e4046cecdd7b384c/client/python/apache_polaris/cli/polaris_cli.py#L60-L97) only exits nonzero when an exception escapes the command. ### To Reproduce From `client/python` on current `main`: ```bash uv run --isolated --frozen python - <<'PY' from unittest.mock import MagicMock from apache_polaris.cli.command.setup import SetupCommand from apache_polaris.cli.constants import Subcommands api = MagicMock() api.list_principal_roles.return_value.roles = [] api.create_principal_role.side_effect = RuntimeError("backend unavailable") command = SetupCommand( setup_subcommand=Subcommands.APPLY, setup_config="unused.yml", _config_cache={"principal_roles": ["required-role"]}, ) command.execute(api) PY echo $? ``` The result is deterministic and was reproduced repeatedly. A matching successful control, with the `side_effect` removed, also exits 0 and creates the role as expected. ### Actual Behavior The failed API operation is logged, but setup returns normally, prints a success message, and exits 0: ```text ERROR Failed to create principal role 'required-role' RuntimeError: backend unavailable INFO === Setup Apply Process Completed Successfully === 0 ``` The existing focused tests also pass without covering this failure contract: ```text uv run --isolated --frozen python -m pytest tests/test_setup_command.py -q .... 4 passed ``` ### Expected Behavior If any requested setup operation fails, the command should not report complete success and should exit nonzero. It can either fail immediately or preserve the current best-effort behavior by continuing, collecting failures, and raising a runtime `CliError` with exit code 1 after processing. The latter would retain partial-progress behavior while making automation reliable. ### Additional context The setup command is documented as an infrastructure-as-code workflow that performs the necessary create and grant operations in order. This behavior has existed since setup was introduced in #3929 and is present in releases 1.4.0 through 1.6.0. #4399 added explicit top-level exit handling for runtime/API failures, but setup's internal exception handling prevents those failures from reaching it. The active setup-related PR #4953 only changes `setup export` presentation and does not address apply failures. ### System information - Polaris revision: `main@7f0528705a2ab08ed4857be3e4046cecdd7b384c` - Polaris Python package version: 1.6.0 - OS: macOS Darwin 25.5.0 arm64 - Python: 3.13.5 - uv: 0.11.13 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
