Skip to content

Commit 5ea4ce6

Browse files
committed
improve exception context
1 parent 5be1e63 commit 5ea4ce6

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

libs/foundry-dev-tools/src/foundry_dev_tools/clients/foundry_sql_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ def query_foundry_sql(
439439
response_json = response.json()
440440

441441
if response_json.get("status", {}).get("type") == "failed":
442-
raise FoundrySqlQueryFailedError(response)
442+
raise FoundrySqlQueryFailedError(response, query=query, branch=branch, dialect=sql_dialect)
443443
if time.time() > start_time + timeout:
444444
raise FoundrySqlQueryClientTimedOutError(response, timeout=timeout)
445445

libs/foundry-dev-tools/src/foundry_dev_tools/errors/sql.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class FoundrySqlQueryFailedError(FoundryAPIError):
1616

1717
message = "Foundry SQL Query Failed."
1818

19-
def __init__(self, response: requests.Response):
19+
def __init__(self, response: requests.Response, **context_kwargs):
2020
kwargs = {}
2121
info = ""
2222

@@ -51,6 +51,9 @@ def __init__(self, response: requests.Response):
5151
# If any error occurs during extraction, fall back to empty
5252
self.error_message = ""
5353

54+
# Merge context kwargs (e.g., query, branch) with extracted error parameters
55+
kwargs.update(context_kwargs)
56+
5457
super().__init__(response=response, info=info, **kwargs)
5558

5659

tests/unit/clients/test_foundry_sql_server.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,54 @@ def test_v2_query_failed_error_details(mocker, test_context_mock):
303303
exception_str = str(exception.value)
304304
assert "COLUMN_NAME" in exception_str
305305
assert "my_table" in exception_str
306+
307+
308+
def test_v2_polling_error_includes_context(mocker, test_context_mock):
309+
"""Test that polling errors include query context for better debugging."""
310+
mocker.patch("time.sleep")
311+
312+
test_query = "SELECT * FROM `ri.foundry.main.dataset.test-dataset`"
313+
314+
# Mock the api_query endpoint (initial query execution)
315+
test_context_mock.mock_adapter.register_uri(
316+
"POST",
317+
build_api_url(TEST_HOST.url, "foundry-sql-server", "sql-endpoint/v1/queries/query"),
318+
json={"type": "running", "running": {"queryHandle": {"queryId": "test-query-id", "type": "foundry"}}},
319+
)
320+
321+
# Mock the api_status endpoint with polling error
322+
test_context_mock.mock_adapter.register_uri(
323+
"POST",
324+
build_api_url(TEST_HOST.url, "foundry-sql-server", "sql-endpoint/v1/queries/status"),
325+
json={
326+
"status": {
327+
"type": "failed",
328+
"failed": {
329+
"errorCode": "ModuleGroupService:ErrorPollingModule",
330+
"errorInstanceId": "5be87070-3aa3-4ed6-aa6a-d9b5041885af",
331+
"errorMessage": "Error polling for job status. Please resubmit.",
332+
"retryable": False,
333+
},
334+
}
335+
},
336+
)
337+
338+
with pytest.raises(FoundrySqlQueryFailedError) as exception:
339+
test_context_mock.foundry_sql_server_v2.query_foundry_sql(test_query)
340+
341+
# Verify error details are extracted
342+
assert exception.value.error_code == "ModuleGroupService:ErrorPollingModule"
343+
assert exception.value.error_instance_id == "5be87070-3aa3-4ed6-aa6a-d9b5041885af"
344+
assert exception.value.error_message == "Error polling for job status. Please resubmit."
345+
346+
# Verify query context is included in the error
347+
assert exception.value.query == test_query
348+
assert exception.value.branch == "master"
349+
assert exception.value.dialect == "SPARK"
350+
351+
# Verify context appears in exception string
352+
exception_str = str(exception.value)
353+
assert "query = " + test_query in exception_str
354+
assert "branch = master" in exception_str
355+
assert "dialect = SPARK" in exception_str
356+
assert "ModuleGroupService:ErrorPollingModule" in exception_str

0 commit comments

Comments
 (0)