snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snowflake/connector/__init__.py +96 -0
- snowflake/connector/_query_context_cache.py +276 -0
- snowflake/connector/_sql_util.py +48 -0
- snowflake/connector/_utils.py +70 -0
- snowflake/connector/arrow_context.py +203 -0
- snowflake/connector/auth/__init__.py +53 -0
- snowflake/connector/auth/_auth.py +586 -0
- snowflake/connector/auth/_http_server.py +220 -0
- snowflake/connector/auth/_oauth_base.py +400 -0
- snowflake/connector/auth/by_plugin.py +219 -0
- snowflake/connector/auth/default.py +36 -0
- snowflake/connector/auth/idtoken.py +72 -0
- snowflake/connector/auth/keypair.py +222 -0
- snowflake/connector/auth/no_auth.py +39 -0
- snowflake/connector/auth/oauth.py +49 -0
- snowflake/connector/auth/oauth_code.py +479 -0
- snowflake/connector/auth/oauth_credentials.py +66 -0
- snowflake/connector/auth/okta.py +335 -0
- snowflake/connector/auth/pat.py +39 -0
- snowflake/connector/auth/usrpwdmfa.py +69 -0
- snowflake/connector/auth/webbrowser.py +502 -0
- snowflake/connector/auth/workload_identity.py +94 -0
- snowflake/connector/azure_storage_client.py +276 -0
- snowflake/connector/backoff_policies.py +141 -0
- snowflake/connector/bind_upload_agent.py +89 -0
- snowflake/connector/cache.py +696 -0
- snowflake/connector/compat.py +127 -0
- snowflake/connector/config_manager.py +496 -0
- snowflake/connector/connection.py +2273 -0
- snowflake/connector/connection_diagnostic.py +776 -0
- snowflake/connector/constants.py +442 -0
- snowflake/connector/converter.py +785 -0
- snowflake/connector/converter_issue23517.py +87 -0
- snowflake/connector/converter_null.py +14 -0
- snowflake/connector/converter_snowsql.py +205 -0
- snowflake/connector/cursor.py +1951 -0
- snowflake/connector/dbapi.py +53 -0
- snowflake/connector/description.py +19 -0
- snowflake/connector/direct_file_operation_utils.py +88 -0
- snowflake/connector/encryption_util.py +220 -0
- snowflake/connector/errorcode.py +91 -0
- snowflake/connector/errors.py +615 -0
- snowflake/connector/externals_utils/__init__.py +0 -0
- snowflake/connector/externals_utils/externals_setup.py +27 -0
- snowflake/connector/feature.py +4 -0
- snowflake/connector/file_compression_type.py +118 -0
- snowflake/connector/file_lock.py +72 -0
- snowflake/connector/file_transfer_agent.py +1215 -0
- snowflake/connector/file_util.py +153 -0
- snowflake/connector/gcs_storage_client.py +474 -0
- snowflake/connector/gzip_decoder.py +85 -0
- snowflake/connector/local_storage_client.py +90 -0
- snowflake/connector/log_configuration.py +60 -0
- snowflake/connector/logging_utils/__init__.py +0 -0
- snowflake/connector/logging_utils/filters.py +72 -0
- snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
- snowflake/connector/network.py +1297 -0
- snowflake/connector/ocsp_asn1crypto.py +447 -0
- snowflake/connector/ocsp_snowflake.py +1883 -0
- snowflake/connector/options.py +131 -0
- snowflake/connector/pandas_tools.py +732 -0
- snowflake/connector/proxy.py +43 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +786 -0
- snowflake/connector/result_set.py +319 -0
- snowflake/connector/s3_storage_client.py +605 -0
- snowflake/connector/secret_detector.py +181 -0
- snowflake/connector/sf_dirs.py +64 -0
- snowflake/connector/sfbinaryformat.py +35 -0
- snowflake/connector/sfdatetime.py +345 -0
- snowflake/connector/snow_logging.py +144 -0
- snowflake/connector/sqlstate.py +9 -0
- snowflake/connector/ssd_internal_keys.py +30 -0
- snowflake/connector/ssl_wrap_socket.py +134 -0
- snowflake/connector/storage_client.py +478 -0
- snowflake/connector/telemetry.py +249 -0
- snowflake/connector/telemetry_oob.py +543 -0
- snowflake/connector/test_util.py +30 -0
- snowflake/connector/time_util.py +159 -0
- snowflake/connector/token_cache.py +402 -0
- snowflake/connector/tool/__init__.py +0 -0
- snowflake/connector/tool/dump_certs.py +57 -0
- snowflake/connector/tool/dump_ocsp_response.py +139 -0
- snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
- snowflake/connector/tool/probe_connection.py +69 -0
- snowflake/connector/url_util.py +49 -0
- snowflake/connector/util_text.py +301 -0
- snowflake/connector/vendored/__init__.py +3 -0
- snowflake/connector/vendored/requests/LICENSE +175 -0
- snowflake/connector/vendored/requests/__init__.py +169 -0
- snowflake/connector/vendored/requests/__version__.py +14 -0
- snowflake/connector/vendored/requests/_internal_utils.py +50 -0
- snowflake/connector/vendored/requests/adapters.py +537 -0
- snowflake/connector/vendored/requests/api.py +157 -0
- snowflake/connector/vendored/requests/auth.py +315 -0
- snowflake/connector/vendored/requests/certs.py +17 -0
- snowflake/connector/vendored/requests/compat.py +79 -0
- snowflake/connector/vendored/requests/cookies.py +561 -0
- snowflake/connector/vendored/requests/exceptions.py +140 -0
- snowflake/connector/vendored/requests/help.py +134 -0
- snowflake/connector/vendored/requests/hooks.py +33 -0
- snowflake/connector/vendored/requests/models.py +1033 -0
- snowflake/connector/vendored/requests/sessions.py +833 -0
- snowflake/connector/vendored/requests/status_codes.py +128 -0
- snowflake/connector/vendored/requests/structures.py +99 -0
- snowflake/connector/vendored/requests/utils.py +1093 -0
- snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
- snowflake/connector/vendored/urllib3/__init__.py +85 -0
- snowflake/connector/vendored/urllib3/_collections.py +355 -0
- snowflake/connector/vendored/urllib3/_version.py +2 -0
- snowflake/connector/vendored/urllib3/connection.py +572 -0
- snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
- snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
- snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
- snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
- snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
- snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
- snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
- snowflake/connector/vendored/urllib3/exceptions.py +323 -0
- snowflake/connector/vendored/urllib3/fields.py +274 -0
- snowflake/connector/vendored/urllib3/filepost.py +98 -0
- snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
- snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
- snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
- snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
- snowflake/connector/vendored/urllib3/request.py +191 -0
- snowflake/connector/vendored/urllib3/response.py +885 -0
- snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
- snowflake/connector/vendored/urllib3/util/connection.py +156 -0
- snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
- snowflake/connector/vendored/urllib3/util/queue.py +22 -0
- snowflake/connector/vendored/urllib3/util/request.py +146 -0
- snowflake/connector/vendored/urllib3/util/response.py +107 -0
- snowflake/connector/vendored/urllib3/util/retry.py +620 -0
- snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
- snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
- snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
- snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
- snowflake/connector/vendored/urllib3/util/url.py +435 -0
- snowflake/connector/vendored/urllib3/util/wait.py +152 -0
- snowflake/connector/version.py +3 -0
- snowflake/connector/wif_util.py +407 -0
- snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
- snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
- snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
- snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
- snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import traceback
|
|
8
|
+
from logging import getLogger
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
|
+
|
|
11
|
+
from .secret_detector import SecretDetector
|
|
12
|
+
from .telemetry import TelemetryData, TelemetryField
|
|
13
|
+
from .time_util import get_time_millis
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
16
|
+
from .connection import SnowflakeConnection
|
|
17
|
+
from .cursor import SnowflakeCursor
|
|
18
|
+
|
|
19
|
+
logger = getLogger(__name__)
|
|
20
|
+
connector_base_path = os.path.join("snowflake", "connector")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
RE_FORMATTED_ERROR = re.compile(r"^(\d{6,})(?: \((\S+)\))?:")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Error(Exception):
|
|
27
|
+
"""Base Snowflake exception class."""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
msg: str | None = None,
|
|
32
|
+
errno: int | None = None,
|
|
33
|
+
sqlstate: str | None = None,
|
|
34
|
+
sfqid: str | None = None,
|
|
35
|
+
query: str | None = None,
|
|
36
|
+
done_format_msg: bool | None = None,
|
|
37
|
+
connection: SnowflakeConnection | None = None,
|
|
38
|
+
cursor: SnowflakeCursor | None = None,
|
|
39
|
+
) -> None:
|
|
40
|
+
super().__init__(msg)
|
|
41
|
+
self.msg = msg
|
|
42
|
+
self.raw_msg = msg
|
|
43
|
+
self.errno = errno or -1
|
|
44
|
+
self.sqlstate = sqlstate or "n/a"
|
|
45
|
+
self.sfqid = sfqid
|
|
46
|
+
self.query = query
|
|
47
|
+
|
|
48
|
+
if self.msg:
|
|
49
|
+
# TODO: If there's a message then check to see if errno (and maybe sqlstate)
|
|
50
|
+
# and if so then don't insert them again, this should eventually be removed
|
|
51
|
+
# and we should be explicitly set this at every call to create these
|
|
52
|
+
# Exceptions.
|
|
53
|
+
# However we shouldn't be creating them during normal execution so
|
|
54
|
+
# this should not affect performance to users and will make our error
|
|
55
|
+
# messages consistent.
|
|
56
|
+
already_formatted_msg = RE_FORMATTED_ERROR.match(msg)
|
|
57
|
+
else:
|
|
58
|
+
self.msg = "Unknown error"
|
|
59
|
+
already_formatted_msg = None
|
|
60
|
+
|
|
61
|
+
if self.errno != -1 and not done_format_msg:
|
|
62
|
+
if self.sqlstate != "n/a":
|
|
63
|
+
if not already_formatted_msg:
|
|
64
|
+
if logger.getEffectiveLevel() in (logging.INFO, logging.DEBUG):
|
|
65
|
+
self.msg = f"{self.errno:06d} ({self.sqlstate}): {self.sfqid}: {self.msg}"
|
|
66
|
+
else:
|
|
67
|
+
self.msg = f"{self.errno:06d} ({self.sqlstate}): {self.msg}"
|
|
68
|
+
else:
|
|
69
|
+
if not already_formatted_msg:
|
|
70
|
+
if logger.getEffectiveLevel() in (logging.INFO, logging.DEBUG):
|
|
71
|
+
self.msg = f"{self.errno:06d}: {self.errno}: {self.msg}"
|
|
72
|
+
else:
|
|
73
|
+
self.msg = f"{self.errno:06d}: {self.msg}"
|
|
74
|
+
|
|
75
|
+
# We want to skip the last frame/line in the traceback since it is the current frame
|
|
76
|
+
self.telemetry_traceback = self.generate_telemetry_stacktrace()
|
|
77
|
+
self.exception_telemetry(msg, cursor, connection)
|
|
78
|
+
|
|
79
|
+
def __repr__(self) -> str:
|
|
80
|
+
return self.__str__()
|
|
81
|
+
|
|
82
|
+
def __str__(self) -> str:
|
|
83
|
+
return self.msg
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def generate_telemetry_stacktrace() -> str:
|
|
87
|
+
# Get the current stack minus this function and the Error init function
|
|
88
|
+
stack_frames = traceback.extract_stack()[:-2]
|
|
89
|
+
filtered_frames = list()
|
|
90
|
+
for frame in stack_frames:
|
|
91
|
+
# Only add frames associated with the snowflake python connector to the telemetry stacktrace
|
|
92
|
+
if connector_base_path in frame.filename:
|
|
93
|
+
# Get the index to truncate the file path to hide any user path
|
|
94
|
+
safe_path_index = frame.filename.find(connector_base_path)
|
|
95
|
+
# Create a new frame with the truncated file name and without the line argument since that can
|
|
96
|
+
# output sensitive data
|
|
97
|
+
filtered_frames.append(
|
|
98
|
+
traceback.FrameSummary(
|
|
99
|
+
frame.filename[safe_path_index:],
|
|
100
|
+
frame.lineno,
|
|
101
|
+
frame.name,
|
|
102
|
+
line="",
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return "".join(traceback.format_list(filtered_frames))
|
|
107
|
+
|
|
108
|
+
def telemetry_msg(self) -> str | None:
|
|
109
|
+
if self.sqlstate != "n/a":
|
|
110
|
+
return f"{self.errno:06d} ({self.sqlstate})"
|
|
111
|
+
elif self.errno != -1:
|
|
112
|
+
return f"{self.errno:06d}"
|
|
113
|
+
else:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
def generate_telemetry_exception_data(
|
|
117
|
+
self,
|
|
118
|
+
) -> dict[str, tuple[bool, str, str] | str]:
|
|
119
|
+
"""Generate the data to send through telemetry."""
|
|
120
|
+
telemetry_data_dict: dict[str, tuple[bool, str, str] | str] = {
|
|
121
|
+
TelemetryField.KEY_STACKTRACE.value: SecretDetector.mask_secrets(
|
|
122
|
+
self.telemetry_traceback
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
telemetry_msg = self.telemetry_msg()
|
|
126
|
+
if self.sfqid:
|
|
127
|
+
telemetry_data_dict[TelemetryField.KEY_SFQID.value] = self.sfqid
|
|
128
|
+
if self.sqlstate:
|
|
129
|
+
telemetry_data_dict[TelemetryField.KEY_SQLSTATE.value] = self.sqlstate
|
|
130
|
+
if telemetry_msg:
|
|
131
|
+
telemetry_data_dict[TelemetryField.KEY_REASON.value] = telemetry_msg
|
|
132
|
+
if self.errno:
|
|
133
|
+
telemetry_data_dict[TelemetryField.KEY_ERROR_NUMBER.value] = str(self.errno)
|
|
134
|
+
|
|
135
|
+
return telemetry_data_dict
|
|
136
|
+
|
|
137
|
+
def send_exception_telemetry(
|
|
138
|
+
self,
|
|
139
|
+
connection: SnowflakeConnection | None,
|
|
140
|
+
telemetry_data: dict[str, Any],
|
|
141
|
+
) -> None:
|
|
142
|
+
"""Send telemetry data by in-band telemetry if it is enabled, otherwise send through out-of-band telemetry."""
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
connection is not None
|
|
146
|
+
and connection.telemetry_enabled
|
|
147
|
+
and not connection._telemetry.is_closed
|
|
148
|
+
):
|
|
149
|
+
# Send with in-band telemetry
|
|
150
|
+
telemetry_data[TelemetryField.KEY_TYPE.value] = (
|
|
151
|
+
TelemetryField.SQL_EXCEPTION.value
|
|
152
|
+
)
|
|
153
|
+
telemetry_data[TelemetryField.KEY_SOURCE.value] = connection.application
|
|
154
|
+
telemetry_data[TelemetryField.KEY_EXCEPTION.value] = self.__class__.__name__
|
|
155
|
+
ts = get_time_millis()
|
|
156
|
+
try:
|
|
157
|
+
connection._log_telemetry(
|
|
158
|
+
TelemetryData.from_telemetry_data_dict(
|
|
159
|
+
from_dict=telemetry_data, timestamp=ts, connection=connection
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
except AttributeError:
|
|
163
|
+
logger.debug("Cursor failed to log to telemetry.", exc_info=True)
|
|
164
|
+
|
|
165
|
+
def exception_telemetry(
|
|
166
|
+
self,
|
|
167
|
+
msg: str,
|
|
168
|
+
cursor: SnowflakeCursor | None,
|
|
169
|
+
connection: SnowflakeConnection | None,
|
|
170
|
+
) -> None:
|
|
171
|
+
"""Main method to generate and send telemetry data for exceptions."""
|
|
172
|
+
try:
|
|
173
|
+
telemetry_data_dict = self.generate_telemetry_exception_data()
|
|
174
|
+
if cursor is not None:
|
|
175
|
+
self.send_exception_telemetry(
|
|
176
|
+
cursor.connection,
|
|
177
|
+
telemetry_data_dict,
|
|
178
|
+
)
|
|
179
|
+
elif connection is not None:
|
|
180
|
+
self.send_exception_telemetry(
|
|
181
|
+
connection,
|
|
182
|
+
telemetry_data_dict,
|
|
183
|
+
)
|
|
184
|
+
else:
|
|
185
|
+
self.send_exception_telemetry(None, telemetry_data_dict)
|
|
186
|
+
except Exception:
|
|
187
|
+
# Do nothing but log if sending telemetry fails
|
|
188
|
+
logger.debug("Sending exception telemetry failed")
|
|
189
|
+
|
|
190
|
+
@staticmethod
|
|
191
|
+
def default_errorhandler(
|
|
192
|
+
connection: SnowflakeConnection,
|
|
193
|
+
cursor: SnowflakeCursor,
|
|
194
|
+
error_class: type[Error],
|
|
195
|
+
error_value: dict[str, str],
|
|
196
|
+
) -> None:
|
|
197
|
+
"""Default error handler that raises an error.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
connection: Connections in which the error happened.
|
|
201
|
+
cursor: Cursor in which the error happened.
|
|
202
|
+
error_class: Class of error that needs handling.
|
|
203
|
+
error_value: A dictionary of the error details.
|
|
204
|
+
|
|
205
|
+
Raises:
|
|
206
|
+
A Snowflake error.
|
|
207
|
+
"""
|
|
208
|
+
errno = error_value.get("errno")
|
|
209
|
+
done_format_msg = error_value.get("done_format_msg")
|
|
210
|
+
raise error_class(
|
|
211
|
+
msg=error_value.get("msg"),
|
|
212
|
+
errno=None if errno is None else int(errno),
|
|
213
|
+
sqlstate=error_value.get("sqlstate"),
|
|
214
|
+
sfqid=error_value.get("sfqid"),
|
|
215
|
+
query=error_value.get("query"),
|
|
216
|
+
done_format_msg=(
|
|
217
|
+
None if done_format_msg is None else bool(done_format_msg)
|
|
218
|
+
),
|
|
219
|
+
connection=connection,
|
|
220
|
+
cursor=cursor,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def errorhandler_wrapper_from_cause(
|
|
225
|
+
connection: SnowflakeConnection,
|
|
226
|
+
cause: Error | Exception,
|
|
227
|
+
cursor: SnowflakeCursor | None = None,
|
|
228
|
+
) -> None:
|
|
229
|
+
"""Wrapper for errorhandler_wrapper, it is called with a cause instead of a dictionary.
|
|
230
|
+
|
|
231
|
+
The dictionary is first extracted from the cause and then it's given to errorhandler_wrapper
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
connection: Connections in which the error happened.
|
|
235
|
+
cursor: Cursor in which the error happened.
|
|
236
|
+
cause: Error instance that we want to handle.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
None if no exceptions are raised by the connection's and cursor's error handlers.
|
|
240
|
+
|
|
241
|
+
Raises:
|
|
242
|
+
A Snowflake error if connection and cursor are None.
|
|
243
|
+
"""
|
|
244
|
+
return Error.errorhandler_wrapper(
|
|
245
|
+
connection,
|
|
246
|
+
cursor,
|
|
247
|
+
type(cause),
|
|
248
|
+
{
|
|
249
|
+
"msg": cause.msg,
|
|
250
|
+
"errno": cause.errno,
|
|
251
|
+
"sqlstate": cause.sqlstate,
|
|
252
|
+
"done_format_msg": True,
|
|
253
|
+
},
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
@staticmethod
|
|
257
|
+
def errorhandler_wrapper(
|
|
258
|
+
connection: SnowflakeConnection | None,
|
|
259
|
+
cursor: SnowflakeCursor | None,
|
|
260
|
+
error_class: type[Error] | type[Exception],
|
|
261
|
+
error_value: dict[str, Any],
|
|
262
|
+
) -> None:
|
|
263
|
+
"""Error handler wrapper that calls the errorhandler method.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
connection: Connections in which the error happened.
|
|
267
|
+
cursor: Cursor in which the error happened.
|
|
268
|
+
error_class: Class of error that needs handling.
|
|
269
|
+
error_value: An optional dictionary of the error details.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
None if no exceptions are raised by the connection's and cursor's error handlers.
|
|
273
|
+
|
|
274
|
+
Raises:
|
|
275
|
+
A Snowflake error if connection, or cursor are None. Otherwise it gives the
|
|
276
|
+
exception to the first handler in that order.
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
handed_over = Error.hand_to_other_handler(
|
|
280
|
+
connection,
|
|
281
|
+
cursor,
|
|
282
|
+
error_class,
|
|
283
|
+
error_value,
|
|
284
|
+
)
|
|
285
|
+
if not handed_over:
|
|
286
|
+
raise Error.errorhandler_make_exception(
|
|
287
|
+
error_class,
|
|
288
|
+
error_value,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
@staticmethod
|
|
292
|
+
def errorhandler_wrapper_from_ready_exception(
|
|
293
|
+
connection: SnowflakeConnection | None,
|
|
294
|
+
cursor: SnowflakeCursor | None,
|
|
295
|
+
error_exc: Error | Exception,
|
|
296
|
+
) -> None:
|
|
297
|
+
"""Like errorhandler_wrapper, but it takes a ready to go Exception."""
|
|
298
|
+
if isinstance(error_exc, Error):
|
|
299
|
+
error_value = {
|
|
300
|
+
"msg": error_exc.msg,
|
|
301
|
+
"errno": error_exc.errno,
|
|
302
|
+
"sqlstate": error_exc.sqlstate,
|
|
303
|
+
"sfqid": error_exc.sfqid,
|
|
304
|
+
}
|
|
305
|
+
else:
|
|
306
|
+
error_value = error_exc.args
|
|
307
|
+
|
|
308
|
+
handed_over = Error.hand_to_other_handler(
|
|
309
|
+
connection,
|
|
310
|
+
cursor,
|
|
311
|
+
type(error_exc),
|
|
312
|
+
error_value,
|
|
313
|
+
)
|
|
314
|
+
if not handed_over:
|
|
315
|
+
raise error_exc
|
|
316
|
+
|
|
317
|
+
@staticmethod
|
|
318
|
+
def hand_to_other_handler(
|
|
319
|
+
connection: SnowflakeConnection | None,
|
|
320
|
+
cursor: SnowflakeCursor | None,
|
|
321
|
+
error_class: type[Error] | type[Exception],
|
|
322
|
+
error_value: dict[str, str | bool],
|
|
323
|
+
) -> bool:
|
|
324
|
+
"""If possible give error to a higher error handler in connection, or cursor.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
Whether it error was successfully given to a handler.
|
|
328
|
+
"""
|
|
329
|
+
error_value.setdefault("done_format_msg", False)
|
|
330
|
+
if connection is not None:
|
|
331
|
+
connection.messages.append((error_class, error_value))
|
|
332
|
+
if cursor is not None:
|
|
333
|
+
cursor.messages.append((error_class, error_value))
|
|
334
|
+
cursor.errorhandler(connection, cursor, error_class, error_value)
|
|
335
|
+
return True
|
|
336
|
+
elif connection is not None:
|
|
337
|
+
connection.errorhandler(connection, cursor, error_class, error_value)
|
|
338
|
+
return True
|
|
339
|
+
return False
|
|
340
|
+
|
|
341
|
+
@staticmethod
|
|
342
|
+
def errorhandler_make_exception(
|
|
343
|
+
error_class: type[Error] | type[Exception],
|
|
344
|
+
error_value: dict[str, str | bool],
|
|
345
|
+
) -> Error | Exception:
|
|
346
|
+
"""Helper function to errorhandler_wrapper that creates the exception."""
|
|
347
|
+
error_value.setdefault("done_format_msg", False)
|
|
348
|
+
|
|
349
|
+
if issubclass(error_class, Error):
|
|
350
|
+
return error_class(
|
|
351
|
+
msg=error_value["msg"],
|
|
352
|
+
errno=error_value.get("errno"),
|
|
353
|
+
sqlstate=error_value.get("sqlstate"),
|
|
354
|
+
sfqid=error_value.get("sfqid"),
|
|
355
|
+
)
|
|
356
|
+
return error_class(error_value)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
class _Warning(Exception):
|
|
360
|
+
"""Exception for important warnings."""
|
|
361
|
+
|
|
362
|
+
pass
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class InterfaceError(Error):
|
|
366
|
+
"""Exception for errors related to the interface."""
|
|
367
|
+
|
|
368
|
+
pass
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
class DatabaseError(Error):
|
|
372
|
+
"""Exception for errors related to the database."""
|
|
373
|
+
|
|
374
|
+
pass
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
class InternalError(DatabaseError):
|
|
378
|
+
"""Exception for errors internal database errors."""
|
|
379
|
+
|
|
380
|
+
pass
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
class OperationalError(DatabaseError):
|
|
384
|
+
"""Exception for errors related to the database's operation."""
|
|
385
|
+
|
|
386
|
+
pass
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class ProgrammingError(DatabaseError):
|
|
390
|
+
"""Exception for errors programming errors."""
|
|
391
|
+
|
|
392
|
+
pass
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class IntegrityError(DatabaseError):
|
|
396
|
+
"""Exception for errors regarding relational integrity."""
|
|
397
|
+
|
|
398
|
+
pass
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class DataError(DatabaseError):
|
|
402
|
+
"""Exception for errors reporting problems with processed data."""
|
|
403
|
+
|
|
404
|
+
pass
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class NotSupportedError(DatabaseError):
|
|
408
|
+
"""Exception for errors when an unsupported database feature was used."""
|
|
409
|
+
|
|
410
|
+
# Not supported errors do not have any PII in their
|
|
411
|
+
def telemetry_msg(self) -> str:
|
|
412
|
+
return self.msg
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
class RevocationCheckError(OperationalError):
|
|
416
|
+
"""Exception for errors during certificate revocation check."""
|
|
417
|
+
|
|
418
|
+
# We already send OCSP exception events
|
|
419
|
+
def exception_telemetry(self, msg, cursor, connection) -> None:
|
|
420
|
+
pass
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
# internal errors
|
|
424
|
+
class InternalServerError(Error):
|
|
425
|
+
"""Exception for 500 HTTP code for retry."""
|
|
426
|
+
|
|
427
|
+
def __init__(self, **kwargs) -> None:
|
|
428
|
+
Error.__init__(
|
|
429
|
+
self,
|
|
430
|
+
msg=kwargs.get("msg") or "HTTP 500: Internal Server Error",
|
|
431
|
+
errno=kwargs.get("errno"),
|
|
432
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
433
|
+
sfqid=kwargs.get("sfqid"),
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class ServiceUnavailableError(Error):
|
|
438
|
+
"""Exception for 503 HTTP code for retry."""
|
|
439
|
+
|
|
440
|
+
def __init__(self, **kwargs) -> None:
|
|
441
|
+
Error.__init__(
|
|
442
|
+
self,
|
|
443
|
+
msg=kwargs.get("msg") or "HTTP 503: Service Unavailable",
|
|
444
|
+
errno=kwargs.get("errno"),
|
|
445
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
446
|
+
sfqid=kwargs.get("sfqid"),
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
class GatewayTimeoutError(Error):
|
|
451
|
+
"""Exception for 504 HTTP error for retry."""
|
|
452
|
+
|
|
453
|
+
def __init__(self, **kwargs) -> None:
|
|
454
|
+
Error.__init__(
|
|
455
|
+
self,
|
|
456
|
+
msg=kwargs.get("msg") or "HTTP 504: Gateway Timeout",
|
|
457
|
+
errno=kwargs.get("errno"),
|
|
458
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
459
|
+
sfqid=kwargs.get("sfqid"),
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class ForbiddenError(Error):
|
|
464
|
+
"""Exception for 403 HTTP error for retry."""
|
|
465
|
+
|
|
466
|
+
def __init__(self, **kwargs) -> None:
|
|
467
|
+
Error.__init__(
|
|
468
|
+
self,
|
|
469
|
+
msg=kwargs.get("msg") or "HTTP 403: Forbidden",
|
|
470
|
+
errno=kwargs.get("errno"),
|
|
471
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
472
|
+
sfqid=kwargs.get("sfqid"),
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class RequestTimeoutError(Error):
|
|
477
|
+
"""Exception for 408 HTTP error for retry."""
|
|
478
|
+
|
|
479
|
+
def __init__(self, **kwargs) -> None:
|
|
480
|
+
Error.__init__(
|
|
481
|
+
self,
|
|
482
|
+
msg=kwargs.get("msg") or "HTTP 408: Request Timeout",
|
|
483
|
+
errno=kwargs.get("errno"),
|
|
484
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
485
|
+
sfqid=kwargs.get("sfqid"),
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
class BadRequest(Error):
|
|
490
|
+
"""Exception for 400 HTTP error for retry."""
|
|
491
|
+
|
|
492
|
+
def __init__(self, **kwargs) -> None:
|
|
493
|
+
Error.__init__(
|
|
494
|
+
self,
|
|
495
|
+
msg=kwargs.get("msg") or "HTTP 400: Bad Request",
|
|
496
|
+
errno=kwargs.get("errno"),
|
|
497
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
498
|
+
sfqid=kwargs.get("sfqid"),
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
class BadGatewayError(Error):
|
|
503
|
+
"""Exception for 502 HTTP error for retry."""
|
|
504
|
+
|
|
505
|
+
def __init__(self, **kwargs) -> None:
|
|
506
|
+
Error.__init__(
|
|
507
|
+
self,
|
|
508
|
+
msg=kwargs.get("msg") or "HTTP 502: Bad Gateway",
|
|
509
|
+
errno=kwargs.get("errno"),
|
|
510
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
511
|
+
sfqid=kwargs.get("sfqid"),
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
class MethodNotAllowed(Error):
|
|
516
|
+
"""Exception for 405 HTTP error for retry."""
|
|
517
|
+
|
|
518
|
+
def __init__(self, **kwargs) -> None:
|
|
519
|
+
Error.__init__(
|
|
520
|
+
self,
|
|
521
|
+
msg=kwargs.get("msg") or "HTTP 405: Method not allowed",
|
|
522
|
+
errno=kwargs.get("errno"),
|
|
523
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
524
|
+
sfqid=kwargs.get("sfqid"),
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
class TooManyRequests(Error):
|
|
529
|
+
"""Exception for 429 HTTP error for retry."""
|
|
530
|
+
|
|
531
|
+
def __init__(self, **kwargs) -> None:
|
|
532
|
+
Error.__init__(
|
|
533
|
+
self,
|
|
534
|
+
msg=kwargs.get("msg") or "HTTP 429: Too Many Requests",
|
|
535
|
+
errno=kwargs.get("errno"),
|
|
536
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
537
|
+
sfqid=kwargs.get("sfqid"),
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
class RefreshTokenError(Error):
|
|
542
|
+
def __init__(self, **kwargs) -> None:
|
|
543
|
+
Error.__init__(
|
|
544
|
+
self,
|
|
545
|
+
msg=kwargs.get("msg") or "Token Refresh Required",
|
|
546
|
+
errno=kwargs.get("errno"),
|
|
547
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
548
|
+
sfqid=kwargs.get("sfqid"),
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
class OtherHTTPRetryableError(Error):
|
|
553
|
+
"""Exception for other HTTP error for retry."""
|
|
554
|
+
|
|
555
|
+
def __init__(self, **kwargs) -> None:
|
|
556
|
+
code = kwargs.get("code", "n/a")
|
|
557
|
+
Error.__init__(
|
|
558
|
+
self,
|
|
559
|
+
msg=kwargs.get("msg") or f"HTTP {code}",
|
|
560
|
+
errno=kwargs.get("errno"),
|
|
561
|
+
sqlstate=kwargs.get("sqlstate"),
|
|
562
|
+
sfqid=kwargs.get("sfqid"),
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
class MissingDependencyError(Error):
|
|
567
|
+
"""Exception for missing extras dependencies."""
|
|
568
|
+
|
|
569
|
+
def __init__(self, dependency: str) -> None:
|
|
570
|
+
super().__init__(msg=f"Missing optional dependency: {dependency}")
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
class BindUploadError(Error):
|
|
574
|
+
"""Exception for bulk array binding stage optimization fails."""
|
|
575
|
+
|
|
576
|
+
pass
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
class RequestExceedMaxRetryError(Error):
|
|
580
|
+
"""Exception for REST call to remote storage API exceeding maximum retries with transient errors."""
|
|
581
|
+
|
|
582
|
+
pass
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
class TokenExpiredError(Error):
|
|
586
|
+
"""Exception for REST call to remote storage API failed because of expired authentication token."""
|
|
587
|
+
|
|
588
|
+
pass
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
class PresignedUrlExpiredError(Error):
|
|
592
|
+
"""Exception for REST call to remote storage API failed because of expired presigned URL."""
|
|
593
|
+
|
|
594
|
+
pass
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
class ConfigSourceError(Error):
|
|
598
|
+
"""Configuration source related errors.
|
|
599
|
+
|
|
600
|
+
Examples are environmental variable and configuration file.
|
|
601
|
+
"""
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
class MissingConfigOptionError(ConfigSourceError):
|
|
605
|
+
"""When a configuration option is missing from the final, resolved configurations.
|
|
606
|
+
|
|
607
|
+
This is a special-case of ConfigSourceError.
|
|
608
|
+
"""
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
class ConfigManagerError(Error):
|
|
612
|
+
"""Configuration manager related errors.
|
|
613
|
+
|
|
614
|
+
This means that ConfigManager is misused by a developer.
|
|
615
|
+
"""
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from snowflake.connector.logging_utils.filters import (
|
|
4
|
+
SecretMaskingFilter,
|
|
5
|
+
add_filter_to_logger_and_children,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
MODULES_TO_MASK_LOGS_NAMES = [
|
|
9
|
+
"snowflake.connector.vendored.urllib3",
|
|
10
|
+
"botocore",
|
|
11
|
+
"boto3",
|
|
12
|
+
]
|
|
13
|
+
# TODO: after migration to the external urllib3 from the vendored one (SNOW-2041970),
|
|
14
|
+
# we should change filters here immediately to the below module's logger:
|
|
15
|
+
# MODULES_TO_MASK_LOGS_NAMES = [ "urllib3", ... ]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def add_filters_to_external_loggers():
|
|
19
|
+
for module_name in MODULES_TO_MASK_LOGS_NAMES:
|
|
20
|
+
add_filter_to_logger_and_children(module_name, SecretMaskingFilter())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def setup_external_libraries():
|
|
24
|
+
"""
|
|
25
|
+
Assures proper setup and injections before any external libraries are used.
|
|
26
|
+
"""
|
|
27
|
+
add_filters_to_external_loggers()
|