Skip to content

Commit 9c348a3

Browse files
amimasJohnVillalovos
authored andcommitted
fix(cli): handle invalid JSON input in CLI options gracefully
Previously, providing malformed JSON to CLI options (such as `--strategies`) resulted in a raw Python traceback (`JSONDecodeError`) surfacing to the user. Additionally, whitespace-only input was implicitly converted to `None`, causing the CLI to send `null` in the API request body, which could be rejected by the GitLab API. This change updates `JsonAttribute` to: - Catch `ValueError` and `TypeError` during JSON parsing. - Raise a `GitlabParsingError`, which the CLI catches to display a user-friendly error message. - Treat whitespace-only strings as invalid JSON rather than `None`, requiring the user to be explicit (e.g. passing `'[]'` or `'{}'`). Tests have been updated to verify the new error handling behavior.
1 parent fc0f3f4 commit 9c348a3

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

gitlab/types.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import json
55
from typing import Any, TYPE_CHECKING
66

7+
from gitlab import exceptions
8+
79

810
@dataclasses.dataclass(frozen=True)
911
class RequiredOptional:
@@ -59,10 +61,12 @@ def get_for_api(self, *, key: str) -> tuple[str, Any]:
5961

6062
class JsonAttribute(GitlabAttribute):
6163
def set_from_cli(self, cli_value: str) -> None:
62-
if not cli_value.strip():
63-
self._value = None
64-
else:
64+
try:
6565
self._value = json.loads(cli_value)
66+
except (ValueError, TypeError) as e:
67+
raise exceptions.GitlabParsingError(
68+
f"Could not parse JSON data: {e}"
69+
) from e
6670

6771

6872
class _ListArrayAttribute(GitlabAttribute):

tests/functional/cli/test_cli_project_feature_flags.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,22 @@ def test_project_feature_flag_cli_update(gitlab_cli, project, feature_flag_cli):
141141
assert ret.success
142142
data = json.loads(ret.stdout)
143143
assert data["active"] is False
144+
145+
146+
def test_project_feature_flag_cli_create_with_malformed_strategies(gitlab_cli, project):
147+
flag_name = "test_flag_cli_malformed_strategies"
148+
strategies_json = '[{"name": "userWithId"' # Malformed JSON
149+
150+
cmd = [
151+
"project-feature-flag",
152+
"create",
153+
"--project-id",
154+
str(project.id),
155+
"--name",
156+
flag_name,
157+
"--strategies",
158+
strategies_json,
159+
]
160+
ret = gitlab_cli(cmd)
161+
assert not ret.success
162+
assert "Could not parse JSON data" in ret.stderr

tests/unit/test_types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from gitlab import types
3+
from gitlab import exceptions, types
44

55

66
class TestRequiredOptional:
@@ -131,8 +131,8 @@ def test_json_attribute() -> None:
131131
attr.set_from_cli('{"key": "value"}')
132132
assert attr.get() == {"key": "value"}
133133

134-
attr.set_from_cli(" ")
135-
assert attr.get() is None
134+
with pytest.raises(exceptions.GitlabParsingError):
135+
attr.set_from_cli(" ")
136136

137137

138138
# CommaSeparatedStringAttribute tests

0 commit comments

Comments
 (0)