This is an automated email from the ASF dual-hosted git repository.
hugh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 95b4c7b7fe chore(bigquery): Add extra logging for BigQuery exceptions
so we can have better insight on exceptions (#22024)
95b4c7b7fe is described below
commit 95b4c7b7fea8ad7c88016d7b332ad68e80ecb0e2
Author: Antonio Rivero Martinez
<[email protected]>
AuthorDate: Thu Nov 10 00:56:08 2022 -0300
chore(bigquery): Add extra logging for BigQuery exceptions so we can have
better insight on exceptions (#22024)
---
superset/db_engine_specs/base.py | 11 +++++-
superset/db_engine_specs/bigquery.py | 9 +++++
tests/unit_tests/db_engine_specs/test_bigquery.py | 41 +++++++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py
index 2a1363e0b6..fb1430ba5e 100644
--- a/superset/db_engine_specs/base.py
+++ b/superset/db_engine_specs/base.py
@@ -430,6 +430,15 @@ class BaseEngineSpec: # pylint:
disable=too-many-public-methods
"""
return {}
+ @classmethod
+ def parse_error_exception(cls, exception: Exception) -> Exception:
+ """
+ Each engine can implement and converge its own specific parser method
+
+ :return: An Exception with a parsed string off the original exception
+ """
+ return exception
+
@classmethod
def get_dbapi_mapped_exception(cls, exception: Exception) -> Exception:
"""
@@ -443,7 +452,7 @@ class BaseEngineSpec: # pylint:
disable=too-many-public-methods
"""
new_exception = cls.get_dbapi_exception_mapping().get(type(exception))
if not new_exception:
- return exception
+ return cls.parse_error_exception(exception)
return new_exception(str(exception))
@classmethod
diff --git a/superset/db_engine_specs/bigquery.py
b/superset/db_engine_specs/bigquery.py
index ffeff31b17..373fc2f747 100644
--- a/superset/db_engine_specs/bigquery.py
+++ b/superset/db_engine_specs/bigquery.py
@@ -578,3 +578,12 @@ class BigQueryEngineSpec(BaseEngineSpec):
"author__name" and "author__email", respectively.
"""
return [column(c["name"]).label(c["name"].replace(".", "__")) for c in
cols]
+
+ @classmethod
+ def parse_error_exception(cls, exception: Exception) -> Exception:
+ try:
+ return
Exception(str(exception).splitlines()[0].rsplit(":")[1].strip())
+ except Exception: # pylint: disable=broad-except
+ # If for some reason we get an exception, for example, no new line
+ # We will return the original exception
+ return exception
diff --git a/tests/unit_tests/db_engine_specs/test_bigquery.py
b/tests/unit_tests/db_engine_specs/test_bigquery.py
index 8c33489faf..4a5c741531 100644
--- a/tests/unit_tests/db_engine_specs/test_bigquery.py
+++ b/tests/unit_tests/db_engine_specs/test_bigquery.py
@@ -244,3 +244,44 @@ def test_mask_encrypted_extra_when_empty() -> None:
from superset.db_engine_specs.bigquery import BigQueryEngineSpec
assert BigQueryEngineSpec.mask_encrypted_extra(None) is None
+
+
+def test_parse_error_message() -> None:
+ """
+ Test that we parse a received message and just extract the useful
information.
+
+ Example errors:
+ bigquery error: 400 Table \"case_detail_all_suites\" must be qualified
with a dataset (e.g. dataset.table).
+
+ (job ID: ddf30b05-44e8-4fbf-aa29-40bfccaed886)
+ -----Query Job SQL Follows-----
+ | . | . | . |\n 1:select * from
case_detail_all_suites\n 2:LIMIT 1001\n | . | . | . |
+ """
+ from superset.db_engine_specs.bigquery import BigQueryEngineSpec
+
+ message = 'bigquery error: 400 Table "case_detail_all_suites" must be
qualified with a dataset (e.g. dataset.table).\n\n(job ID:
ddf30b05-44e8-4fbf-aa29-40bfccaed886)\n\n -----Query Job SQL Follows-----
\n\n | . | . | . |\n 1:select * from
case_detail_all_suites\n 2:LIMIT 1001\n | . | . | . |'
+ expected_result = '400 Table "case_detail_all_suites" must be qualified
with a dataset (e.g. dataset.table).'
+ assert (
+ str(BigQueryEngineSpec.parse_error_exception(Exception(message)))
+ == expected_result
+ )
+
+
+def test_parse_error_raises_exception() -> None:
+ """
+ Test that we handle any exception we might get from calling the
parse_error_exception method.
+
+ Example errors:
+ 400 Syntax error: Expected "(" or keyword UNNEST but got "@" at [4:80]
+ bigquery error: 400 Table \"case_detail_all_suites\" must be qualified
with a dataset (e.g. dataset.table).
+ """
+ from superset.db_engine_specs.bigquery import BigQueryEngineSpec
+
+ message = 'bigquery error: 400 Table "case_detail_all_suites" must be
qualified with a dataset (e.g. dataset.table).'
+ message_2 = "6"
+ expected_result = '400 Table "case_detail_all_suites" must be qualified
with a dataset (e.g. dataset.table).'
+ assert (
+ str(BigQueryEngineSpec.parse_error_exception(Exception(message)))
+ == expected_result
+ )
+ assert str(BigQueryEngineSpec.parse_error_exception(Exception(message_2)))
== "6"