fix: catch exception when create connection (#16692)

* fix: catch exception when create connection

* fix lint

* added UT
diff --git a/superset/db_engine_specs/bigquery.py b/superset/db_engine_specs/bigquery.py
index 7349844..ccd28e7 100644
--- a/superset/db_engine_specs/bigquery.py
+++ b/superset/db_engine_specs/bigquery.py
@@ -17,7 +17,7 @@
 import re
 import urllib
 from datetime import datetime
-from typing import Any, Dict, List, Optional, Pattern, Tuple, TYPE_CHECKING
+from typing import Any, Dict, List, Optional, Pattern, Tuple, Type, TYPE_CHECKING
 
 import pandas as pd
 from apispec import APISpec
@@ -32,6 +32,7 @@
 
 from superset.databases.schemas import encrypted_field_properties, EncryptedField
 from superset.db_engine_specs.base import BaseEngineSpec
+from superset.db_engine_specs.exceptions import SupersetDBAPIDisconnectionError
 from superset.errors import SupersetError, SupersetErrorType
 from superset.sql_parse import Table
 from superset.utils import core as utils
@@ -389,6 +390,13 @@
         raise ValidationError("Invalid service credentials")
 
     @classmethod
+    def get_dbapi_exception_mapping(cls) -> Dict[Type[Exception], Type[Exception]]:
+        # pylint: disable=import-error,import-outside-toplevel
+        from google.auth.exceptions import DefaultCredentialsError
+
+        return {DefaultCredentialsError: SupersetDBAPIDisconnectionError}
+
+    @classmethod
     def validate_parameters(
         cls, parameters: BigQueryParametersType  # pylint: disable=unused-argument
     ) -> List[SupersetError]:
diff --git a/superset/models/core.py b/superset/models/core.py
index 6144345..1ea60e6 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -371,7 +371,10 @@
                 sqlalchemy_url, params, effective_username, security_manager, source
             )
 
-        return create_engine(sqlalchemy_url, **params)
+        try:
+            return create_engine(sqlalchemy_url, **params)
+        except Exception as ex:
+            raise self.db_engine_spec.get_dbapi_mapped_exception(ex)
 
     def get_reserved_words(self) -> Set[str]:
         return self.get_dialect().preparer.reserved_words
diff --git a/tests/integration_tests/model_tests.py b/tests/integration_tests/model_tests.py
index 567fdfe..c8499ce 100644
--- a/tests/integration_tests/model_tests.py
+++ b/tests/integration_tests/model_tests.py
@@ -18,6 +18,8 @@
 import textwrap
 import unittest
 from unittest import mock
+
+from superset.exceptions import SupersetException
 from tests.integration_tests.fixtures.birth_names_dashboard import (
     load_birth_names_dashboard_with_slices,
 )
@@ -337,6 +339,18 @@
             df = main_db.get_df("USE superset; SELECT ';';", None)
             self.assertEqual(df.iat[0, 0], ";")
 
+    @mock.patch("superset.models.core.create_engine")
+    def test_get_sqla_engine(self, mocked_create_engine):
+        model = Database(
+            database_name="test_database", sqlalchemy_uri="mysql://root@localhost",
+        )
+        model.db_engine_spec.get_dbapi_exception_mapping = mock.Mock(
+            return_value={Exception: SupersetException}
+        )
+        mocked_create_engine.side_effect = Exception()
+        with self.assertRaises(SupersetException):
+            model.get_sqla_engine()
+
 
 class TestSqlaTableModel(SupersetTestCase):
     @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")