Skip to content

Commit 77faef4

Browse files
authored
[Trino] Ensures uninterrupted schema listing even if a catalog query fails (#3939)
1 parent c54f745 commit 77faef4

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

desktop/libs/notebook/src/notebook/connectors/trino.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import json
1919
import time
20+
import logging
2021
import textwrap
2122
from urllib.parse import urlparse
2223

@@ -35,6 +36,8 @@
3536
from desktop.lib.rest.resource import Resource
3637
from notebook.connectors.base import Api, ExecutionWrapper, QueryError, ResultWrapper
3738

39+
LOG = logging.getLogger()
40+
3841

3942
def query_error_handler(func):
4043
def decorator(*args, **kwargs):
@@ -297,12 +300,18 @@ def _show_databases(self):
297300
databases = []
298301

299302
for catalog in catalogs:
300-
query_client = TrinoQuery(self.trino_request, 'SHOW SCHEMAS FROM ' + catalog)
301-
response = query_client.execute()
302-
databases += [f'{catalog}.{item}' for sublist in response.rows for item in sublist]
303+
try:
304+
query_client = TrinoQuery(self.trino_request, 'SHOW SCHEMAS FROM ' + catalog)
305+
response = query_client.execute()
306+
databases += [f'{catalog}.{item}' for sublist in response.rows for item in sublist]
307+
except Exception as e:
308+
# Log the exception and continue with the next catalog
309+
LOG.error(f"Failed to fetch schemas from catalog {catalog}: {str(e)}")
310+
continue
303311

304312
return databases
305313

314+
@query_error_handler
306315
def _show_catalogs(self):
307316
query_client = TrinoQuery(self.trino_request, 'SHOW CATALOGS')
308317
response = query_client.execute()
@@ -311,6 +320,7 @@ def _show_catalogs(self):
311320

312321
return catalogs
313322

323+
@query_error_handler
314324
def _show_tables(self, database):
315325
database = self._format_identifier(database, is_db=True)
316326
query_client = TrinoQuery(self.trino_request, 'USE ' + database)
@@ -326,6 +336,7 @@ def _show_tables(self, database):
326336
for table in tables
327337
]
328338

339+
@query_error_handler
329340
def _get_columns(self, database, table):
330341
database = self._format_identifier(database, is_db=True)
331342
query_client = TrinoQuery(self.trino_request, 'USE ' + database)

desktop/libs/notebook/src/notebook/connectors/trino_tests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,26 @@ def test_get_log(self):
380380
result = self.trino_api.get_log(notebook, snippet)
381381

382382
assert result == expected_log
383+
384+
def test_show_databases(self):
385+
with patch('notebook.connectors.trino.LOG.error') as Log_error:
386+
with patch('notebook.connectors.trino.TrinoQuery') as TrinoQuery:
387+
with patch('notebook.connectors.trino.TrinoApi._show_catalogs') as _show_catalogs:
388+
_show_catalogs.return_value = [
389+
'catalog1', 'catalog2'
390+
]
391+
query_instance = TrinoQuery.return_value
392+
query_instance.execute.side_effect = [
393+
MagicMock(rows=[["schema1"], ["schema2"]]), # First catalog response
394+
Exception("Some error") # Second catalog raises an exception
395+
]
396+
result = self.trino_api._show_databases()
397+
398+
# Assert the expected output
399+
expected_result = ['catalog1.schema1', 'catalog1.schema2']
400+
self.assertEqual(result, expected_result)
401+
402+
# Assert error logging was called for the exception
403+
Log_error.assert_called_once_with(
404+
"Failed to fetch schemas from catalog catalog2: Some error"
405+
)

0 commit comments

Comments
 (0)