@@ -233,3 +233,73 @@ def test_v2_invalid_compression_codec(test_context_mock):
233233 "SELECT * FROM `ri.foundry.main.dataset.test-dataset`" ,
234234 arrow_compression_codec = "INVALID" , # type: ignore[arg-type]
235235 )
236+
237+
238+ def test_v2_query_failed_error_details (mocker , test_context_mock ):
239+ """Test that V2 error responses with rich parameters are properly extracted."""
240+ mocker .patch ("time.sleep" )
241+
242+ # Mock the api_query endpoint (initial query execution)
243+ test_context_mock .mock_adapter .register_uri (
244+ "POST" ,
245+ build_api_url (TEST_HOST .url , "foundry-sql-server" , "sql-endpoint/v1/queries/query" ),
246+ json = {"type" : "running" , "running" : {"queryHandle" : {"queryId" : "test-query-id" , "type" : "foundry" }}},
247+ )
248+
249+ # Mock the api_status endpoint with V2 error structure containing rich parameters
250+ test_context_mock .mock_adapter .register_uri (
251+ "POST" ,
252+ build_api_url (TEST_HOST .url , "foundry-sql-server" , "sql-endpoint/v1/queries/status" ),
253+ json = {
254+ "status" : {
255+ "type" : "failed" ,
256+ "failed" : {
257+ "errorCode" : "INVALID_ARGUMENT" ,
258+ "errorName" : "SqlQueryService:SqlSyntaxError" ,
259+ "errorInstanceId" : "c16cb2b7-01ec-42a9-9ee2-0e57e2aed4ba" ,
260+ "parameters" : {
261+ "endLine" : 1 ,
262+ "endColumn" : 15350 ,
263+ "dialect" : "SPARK" ,
264+ "queryFragment" : "" ,
265+ "startColumn" : 15340 ,
266+ "startLine" : 1 ,
267+ "userFriendlyMessage" : (
268+ "From line 1, column 15340 to line 1, column 15350: "
269+ "Column 'COLUMN_NAME' not found in table 'my_table'; did you mean 'column_name'?"
270+ ),
271+ },
272+ },
273+ }
274+ },
275+ )
276+
277+ with pytest .raises (FoundrySqlQueryFailedError ) as exception :
278+ test_context_mock .foundry_sql_server_v2 .query_foundry_sql (
279+ "SELECT COLUMN_NAME FROM `ri.foundry.main.dataset.test-dataset`" ,
280+ )
281+
282+ # Verify all error parameters are extracted and accessible
283+ assert exception .value .error_code == "INVALID_ARGUMENT"
284+ assert exception .value .error_name == "SqlQueryService:SqlSyntaxError"
285+ assert exception .value .error_instance_id == "c16cb2b7-01ec-42a9-9ee2-0e57e2aed4ba"
286+
287+ # Verify parameters are converted from camelCase to snake_case and accessible
288+ assert exception .value .start_line == 1
289+ assert exception .value .end_line == 1
290+ assert exception .value .start_column == 15340
291+ assert exception .value .end_column == 15350
292+ assert exception .value .dialect == "SPARK"
293+ # query_fragment is in kwargs even if empty
294+ assert "query_fragment" in exception .value .kwargs
295+
296+ # Verify userFriendlyMessage is used as the info text and accessible
297+ assert exception .value .user_friendly_message == (
298+ "From line 1, column 15340 to line 1, column 15350: "
299+ "Column 'COLUMN_NAME' not found in table 'my_table'; did you mean 'column_name'?"
300+ )
301+
302+ # Verify the exception message string includes the user-friendly message
303+ exception_str = str (exception .value )
304+ assert "COLUMN_NAME" in exception_str
305+ assert "my_table" in exception_str
0 commit comments