Skip to content

Commit 2991ffd

Browse files
committed
🐛 Improve error message when receiving a 403
1 parent 7bef357 commit 2991ffd

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

src/fastapi_cloud_cli/utils/api.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ def _handle_unauthorized(auth_mode: AuthMode) -> str:
209209
return message
210210

211211

212+
def _get_response_error_message(response: httpx.Response) -> str | None:
213+
try:
214+
data = response.json()
215+
except (json.JSONDecodeError, httpx.ResponseNotRead):
216+
return None
217+
218+
try:
219+
return data["detail"]
220+
except (KeyError, TypeError):
221+
return None
222+
223+
212224
def handle_http_error(
213225
error: httpx.HTTPError,
214226
default_message: str | None = None,
@@ -227,7 +239,10 @@ def handle_http_error(
227239
message = _handle_unauthorized(auth_mode=auth_mode)
228240

229241
elif status_code == 403:
230-
message = "You don't have permissions for this resource"
242+
message = (
243+
_get_response_error_message(error.response)
244+
or "You don't have permissions for this resource"
245+
)
231246

232247
if not message:
233248
message = (

tests/test_cli_deploy.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,35 @@ def test_creates_app_on_backend(
461461
assert "App created successfully" in result.output
462462

463463

464+
@pytest.mark.respx
465+
def test_shows_api_message_when_create_app_is_forbidden(
466+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
467+
) -> None:
468+
steps = [Keys.ENTER, Keys.ENTER, *"demo", Keys.ENTER, Keys.ENTER, Keys.ENTER]
469+
team = _get_random_team()
470+
471+
respx_mock.get("/teams/").mock(return_value=Response(200, json={"data": [team]}))
472+
respx_mock.post(
473+
"/apps/", json={"name": "demo", "team_id": team["id"], "directory": None}
474+
).mock(
475+
return_value=Response(
476+
403,
477+
json={"detail": "App limit reached"},
478+
)
479+
)
480+
481+
with (
482+
changing_dir(tmp_path),
483+
patch("rich_toolkit.container.getchar") as mock_getchar,
484+
):
485+
mock_getchar.side_effect = steps
486+
487+
result = runner.invoke(app, ["deploy"])
488+
489+
assert result.exit_code == 1
490+
assert "App limit reached" in result.output
491+
492+
464493
@pytest.mark.respx
465494
def test_creates_app_with_directory(
466495
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter

0 commit comments

Comments
 (0)