Skip to content

Commit 85c2dbf

Browse files
committed
Handle 'ItemDisplayNameNotAvailableYet' in warehouse creation
1 parent ce7109b commit 85c2dbf

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

sqlmesh/core/engine_adapter/fabric.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import typing as t
44
import logging
55
import requests
6+
import time
67
from functools import cached_property
78
from sqlglot import exp
89
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_result
@@ -15,6 +16,7 @@
1516
from sqlmesh.utils.errors import SQLMeshError
1617
from sqlmesh.utils.connection_pool import ConnectionPool
1718

19+
1820
if t.TYPE_CHECKING:
1921
from sqlmesh.core._typing import TableName
2022

@@ -172,8 +174,15 @@ def __init__(self, tenant_id: str, workspace_id: str, client_id: str, client_sec
172174
self.client_secret = client_secret
173175
self.workspace_id = workspace_id
174176

175-
def create_warehouse(self, warehouse_name: str, if_not_exists: bool = True) -> None:
177+
def create_warehouse(
178+
self, warehouse_name: str, if_not_exists: bool = True, attempt: int = 0
179+
) -> None:
176180
"""Create a catalog (warehouse) in Microsoft Fabric via REST API."""
181+
182+
# attempt count is arbitrary, it essentially equates to 30 seconds max wait with the time.sleep() below
183+
if attempt > 3:
184+
raise SQLMeshError("Gave up waiting for warehouse to become available")
185+
177186
logger.info(f"Creating Fabric warehouse: {warehouse_name}")
178187

179188
request_data = {
@@ -186,12 +195,28 @@ def create_warehouse(self, warehouse_name: str, if_not_exists: bool = True) -> N
186195
if (
187196
if_not_exists
188197
and response.status_code == 400
189-
and response.json().get("errorCode", None) == "ItemDisplayNameAlreadyInUse"
198+
and (errorCode := response.json().get("errorCode", None))
190199
):
191-
logger.warning(f"Fabric warehouse {warehouse_name} already exists")
192-
return
193-
194-
response.raise_for_status()
200+
if errorCode == "ItemDisplayNameAlreadyInUse":
201+
logger.warning(f"Fabric warehouse {warehouse_name} already exists")
202+
return
203+
if errorCode == "ItemDisplayNameNotAvailableYet":
204+
logger.warning(f"Fabric warehouse {warehouse_name} is still spinning up; waiting")
205+
time.sleep(
206+
10
207+
) # arbitrary, seems to be "good enough" at least in CI. I was unable to find any guidance in the MS docs on how to handle this case
208+
return self.create_warehouse(
209+
warehouse_name=warehouse_name, if_not_exists=if_not_exists, attempt=attempt + 1
210+
)
211+
212+
try:
213+
response.raise_for_status()
214+
except:
215+
# the important information to actually debug anything is in the response body which Requests never prints
216+
logger.exception(
217+
f"Failed to create warehouse {warehouse_name}. status: {response.status_code}, body: {response.text}"
218+
)
219+
raise
195220

196221
# Handle direct success (201) or async creation (202)
197222
if response.status_code == 201:

tests/core/engine_adapter/integration/test_integration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3607,6 +3607,7 @@ def test_identifier_length_limit(ctx: TestContext):
36073607
EnvironmentSuffixTarget.CATALOG,
36083608
],
36093609
)
3610+
@pytest.mark.xdist_group("serial")
36103611
def test_janitor(
36113612
ctx: TestContext, tmp_path: pathlib.Path, environment_suffix_target: EnvironmentSuffixTarget
36123613
):

0 commit comments

Comments
 (0)