diff --git a/src/prefect/cli/dashboard.py b/src/prefect/cli/dashboard.py index 9ead1988490c..a7b2caea7145 100644 --- a/src/prefect/cli/dashboard.py +++ b/src/prefect/cli/dashboard.py @@ -4,7 +4,7 @@ from prefect.cli._utilities import exit_with_success from prefect.cli.cloud import get_current_workspace from prefect.cli.root import app -from prefect.client.cloud import get_cloud_client +from prefect.client.cloud import CloudUnauthorizedError, get_cloud_client from prefect.settings import PREFECT_UI_URL from prefect.utilities.asyncutils import run_sync_in_worker_thread @@ -29,7 +29,10 @@ async def open(): await run_sync_in_worker_thread(webbrowser.open_new_tab, ui_url) async with get_cloud_client() as client: - current_workspace = get_current_workspace(await client.read_workspaces()) + try: + current_workspace = get_current_workspace(await client.read_workspaces()) + except CloudUnauthorizedError: + current_workspace = None destination = ( f"{current_workspace.account_handle}/{current_workspace.workspace_handle}" diff --git a/tests/cli/test_dashboard.py b/tests/cli/test_dashboard.py index 77f3020e4f41..a3f479b54c8d 100644 --- a/tests/cli/test_dashboard.py +++ b/tests/cli/test_dashboard.py @@ -102,3 +102,36 @@ def test_open_current_workspace_in_browser_failure_no_workspace_set( with use_profile("logged-in-profile"): invoke_and_assert(["dashboard", "open"], expected_code=0) + + +@pytest.mark.usefixtures("mock_webbrowser") +@pytest.mark.parametrize("api_url", ["http://localhost:4200", "https://api.prefect.io"]) +def test_open_current_workspace_in_browser_failure_unauthorized(respx_mock, api_url): + save_profiles( + ProfilesCollection( + [ + Profile( + name="logged-in-profile", + settings={ + PREFECT_API_URL: api_url, + PREFECT_API_KEY: "invalid_key", + }, + ) + ], + active="logged-in-profile", + ) + ) + + respx_mock.get(PREFECT_CLOUD_API_URL.value() + "/me/workspaces").mock( + return_value=httpx.Response( + status.HTTP_401_UNAUTHORIZED, + json={"detail": "Unauthorized"}, + ) + ) + + with use_profile("logged-in-profile"): + invoke_and_assert( + ["dashboard", "open"], + expected_code=0, + expected_output_contains=f"Opened {api_url!r} in browser.", + )