Skip to content

Commit 0a8540f

Browse files
committed
🐛 Fix deploy command error handling
1 parent cd2e0ba commit 0a8540f

3 files changed

Lines changed: 24 additions & 19 deletions

File tree

src/fastapi_cloud_cli/commands/deploy.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from enum import Enum
77
from itertools import cycle
88
from pathlib import Path
9+
from textwrap import dedent
910
from typing import Any, Dict, List, Optional, Union
1011

1112
import fastar
@@ -388,12 +389,15 @@ def _wait_for_deployment(
388389

389390
last_message_changed_at = time.monotonic()
390391

391-
except (BuildLogError, TooManyRetriesError) as e:
392-
logger.error("Build log streaming failed: %s", e)
393-
toolkit.print_line()
394-
toolkit.print(
395-
f"⚠️ Unable to stream build logs. Check the dashboard for status: [link={deployment.dashboard_url}]{deployment.dashboard_url}[/link]"
392+
except (BuildLogError, TooManyRetriesError, TimeoutError) as e:
393+
progress.set_error(
394+
dedent(f"""
395+
[error]Build log streaming failed: {e}[/]
396+
397+
Unable to stream build logs. Check the dashboard for status: [link={deployment.dashboard_url}]{deployment.dashboard_url}[/link]
398+
""").strip()
396399
)
400+
397401
raise typer.Exit(1) from e
398402

399403

src/fastapi_cloud_cli/utils/api.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Generator[T, None, None]:
114114
for attempt_number in range(total_attempts):
115115
if time.monotonic() - start > timeout.total_seconds():
116116
raise TimeoutError(
117-
"Build log streaming timed out after %ds",
118-
timeout.total_seconds(),
117+
f"Build log streaming timed out after {timeout.total_seconds():.0f}s"
119118
)
120119

121120
with attempt(attempt_number):

tests/test_cli_deploy.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from fastapi_cloud_cli.cli import app
1717
from fastapi_cloud_cli.config import Settings
18+
from fastapi_cloud_cli.utils.api import BuildLogError, TooManyRetriesError
1819
from tests.conftest import ConfiguredApp
1920
from tests.utils import Keys, build_logs_response, changing_dir
2021

@@ -771,11 +772,14 @@ def test_shows_no_apps_found_message_when_team_has_no_apps(
771772
)
772773

773774

775+
@pytest.mark.parametrize(
776+
"error",
777+
[BuildLogError, TooManyRetriesError, TimeoutError],
778+
)
774779
@pytest.mark.respx(base_url=settings.base_api_url)
775-
def test_handles_build_log_streaming_error(
776-
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
780+
def test_shows_error_message_on_build_exception(
781+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter, error: Exception
777782
) -> None:
778-
"""Test that BuildLogError is caught and shows dashboard link (lines 384, 387-392)."""
779783
app_data = _get_random_app()
780784
team_data = _get_random_team()
781785
app_id = app_data["id"]
@@ -802,11 +806,10 @@ def test_handles_build_log_streaming_error(
802806
return_value=Response(200)
803807
)
804808

805-
respx_mock.get(f"/deployments/{deployment_data['id']}/build-logs").mock(
806-
return_value=Response(422, text="Error")
807-
)
808-
809-
with changing_dir(tmp_path):
809+
with changing_dir(tmp_path), patch(
810+
"fastapi_cloud_cli.utils.api.APIClient.stream_build_logs",
811+
side_effect=error,
812+
):
810813
result = runner.invoke(app, ["deploy"])
811814

812815
assert result.exit_code == 1
@@ -815,10 +818,8 @@ def test_handles_build_log_streaming_error(
815818

816819

817820
@pytest.mark.respx(base_url=settings.base_api_url)
818-
def test_shows_error_message_when_build_log_streaming_fails(
819-
logged_in_cli: None,
820-
tmp_path: Path,
821-
respx_mock: respx.MockRouter,
821+
def test_shows_error_message_on_build_log_http_error(
822+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
822823
) -> None:
823824
app_data = _get_random_app()
824825
team_data = _get_random_team()
@@ -853,6 +854,7 @@ def test_shows_error_message_when_build_log_streaming_fails(
853854
with changing_dir(tmp_path), patch("time.sleep"):
854855
result = runner.invoke(app, ["deploy"])
855856

857+
assert result.exit_code == 1
856858
assert "Unable to stream build logs" in result.output
857859
assert deployment_data["dashboard_url"] in result.output
858860

0 commit comments

Comments
 (0)