snowpark-connect 0.30.1__py3-none-any.whl → 0.31.0__py3-none-any.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.

Potentially problematic release.


This version of snowpark-connect might be problematic. Click here for more details.

Files changed (78) hide show
  1. snowflake/snowpark_connect/column_name_handler.py +150 -25
  2. snowflake/snowpark_connect/config.py +51 -16
  3. snowflake/snowpark_connect/date_time_format_mapping.py +71 -13
  4. snowflake/snowpark_connect/error/error_codes.py +50 -0
  5. snowflake/snowpark_connect/error/error_utils.py +142 -22
  6. snowflake/snowpark_connect/error/exceptions.py +13 -4
  7. snowflake/snowpark_connect/execute_plan/map_execution_command.py +5 -1
  8. snowflake/snowpark_connect/execute_plan/map_execution_root.py +5 -1
  9. snowflake/snowpark_connect/execute_plan/utils.py +5 -1
  10. snowflake/snowpark_connect/expression/function_defaults.py +9 -2
  11. snowflake/snowpark_connect/expression/literal.py +7 -1
  12. snowflake/snowpark_connect/expression/map_cast.py +17 -5
  13. snowflake/snowpark_connect/expression/map_expression.py +48 -4
  14. snowflake/snowpark_connect/expression/map_extension.py +25 -5
  15. snowflake/snowpark_connect/expression/map_sql_expression.py +65 -30
  16. snowflake/snowpark_connect/expression/map_udf.py +10 -2
  17. snowflake/snowpark_connect/expression/map_unresolved_attribute.py +33 -9
  18. snowflake/snowpark_connect/expression/map_unresolved_function.py +627 -205
  19. snowflake/snowpark_connect/expression/map_unresolved_star.py +5 -1
  20. snowflake/snowpark_connect/expression/map_update_fields.py +14 -4
  21. snowflake/snowpark_connect/expression/map_window_function.py +18 -3
  22. snowflake/snowpark_connect/relation/catalogs/abstract_spark_catalog.py +65 -17
  23. snowflake/snowpark_connect/relation/catalogs/snowflake_catalog.py +34 -12
  24. snowflake/snowpark_connect/relation/catalogs/utils.py +12 -4
  25. snowflake/snowpark_connect/relation/io_utils.py +6 -1
  26. snowflake/snowpark_connect/relation/map_catalog.py +5 -1
  27. snowflake/snowpark_connect/relation/map_column_ops.py +88 -56
  28. snowflake/snowpark_connect/relation/map_extension.py +28 -8
  29. snowflake/snowpark_connect/relation/map_join.py +21 -10
  30. snowflake/snowpark_connect/relation/map_local_relation.py +5 -1
  31. snowflake/snowpark_connect/relation/map_relation.py +33 -7
  32. snowflake/snowpark_connect/relation/map_row_ops.py +23 -7
  33. snowflake/snowpark_connect/relation/map_sql.py +91 -24
  34. snowflake/snowpark_connect/relation/map_stats.py +5 -1
  35. snowflake/snowpark_connect/relation/map_udtf.py +14 -4
  36. snowflake/snowpark_connect/relation/read/jdbc_read_dbapi.py +49 -13
  37. snowflake/snowpark_connect/relation/read/map_read.py +15 -3
  38. snowflake/snowpark_connect/relation/read/map_read_csv.py +11 -3
  39. snowflake/snowpark_connect/relation/read/map_read_jdbc.py +17 -5
  40. snowflake/snowpark_connect/relation/read/map_read_json.py +8 -2
  41. snowflake/snowpark_connect/relation/read/map_read_parquet.py +13 -3
  42. snowflake/snowpark_connect/relation/read/map_read_socket.py +11 -3
  43. snowflake/snowpark_connect/relation/read/map_read_table.py +15 -5
  44. snowflake/snowpark_connect/relation/read/map_read_text.py +5 -1
  45. snowflake/snowpark_connect/relation/read/metadata_utils.py +5 -1
  46. snowflake/snowpark_connect/relation/stage_locator.py +5 -1
  47. snowflake/snowpark_connect/relation/write/jdbc_write_dbapi.py +19 -3
  48. snowflake/snowpark_connect/relation/write/map_write.py +131 -34
  49. snowflake/snowpark_connect/relation/write/map_write_jdbc.py +8 -2
  50. snowflake/snowpark_connect/resources_initializer.py +5 -1
  51. snowflake/snowpark_connect/server.py +72 -19
  52. snowflake/snowpark_connect/type_mapping.py +54 -17
  53. snowflake/snowpark_connect/utils/context.py +42 -1
  54. snowflake/snowpark_connect/utils/describe_query_cache.py +3 -0
  55. snowflake/snowpark_connect/utils/env_utils.py +5 -1
  56. snowflake/snowpark_connect/utils/identifiers.py +11 -3
  57. snowflake/snowpark_connect/utils/pandas_udtf_utils.py +8 -4
  58. snowflake/snowpark_connect/utils/profiling.py +25 -8
  59. snowflake/snowpark_connect/utils/scala_udf_utils.py +11 -3
  60. snowflake/snowpark_connect/utils/session.py +5 -1
  61. snowflake/snowpark_connect/utils/telemetry.py +6 -0
  62. snowflake/snowpark_connect/utils/temporary_view_cache.py +5 -1
  63. snowflake/snowpark_connect/utils/udf_cache.py +5 -3
  64. snowflake/snowpark_connect/utils/udf_helper.py +20 -6
  65. snowflake/snowpark_connect/utils/udf_utils.py +4 -4
  66. snowflake/snowpark_connect/utils/udtf_helper.py +5 -1
  67. snowflake/snowpark_connect/utils/udtf_utils.py +34 -26
  68. snowflake/snowpark_connect/version.py +1 -1
  69. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/METADATA +3 -2
  70. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/RECORD +78 -77
  71. {snowpark_connect-0.30.1.data → snowpark_connect-0.31.0.data}/scripts/snowpark-connect +0 -0
  72. {snowpark_connect-0.30.1.data → snowpark_connect-0.31.0.data}/scripts/snowpark-session +0 -0
  73. {snowpark_connect-0.30.1.data → snowpark_connect-0.31.0.data}/scripts/snowpark-submit +0 -0
  74. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/WHEEL +0 -0
  75. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/licenses/LICENSE-binary +0 -0
  76. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/licenses/LICENSE.txt +0 -0
  77. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/licenses/NOTICE-binary +0 -0
  78. {snowpark_connect-0.30.1.dist-info → snowpark_connect-0.31.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,8 @@ import pyspark.sql.connect.proto.relations_pb2 as relation_proto
9
9
  from snowflake import snowpark
10
10
  from snowflake.snowpark._internal.analyzer.analyzer_utils import unquote_if_quoted
11
11
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
12
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
13
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
12
14
  from snowflake.snowpark_connect.relation.read.jdbc_read_dbapi import JdbcDataFrameReader
13
15
  from snowflake.snowpark_connect.relation.read.utils import (
14
16
  Connection,
@@ -28,7 +30,9 @@ def create_connection(jdbc_options: dict[str, str]) -> Connection:
28
30
  return jaydebeapi.connect(driver, url, jdbc_options)
29
31
  except Exception as e:
30
32
  jpype.detachThreadFromJVM()
31
- raise Exception(f"Error connecting JDBC datasource: {e}")
33
+ exception = Exception(f"Error connecting JDBC datasource: {e}")
34
+ attach_custom_error_code(exception, ErrorCodes.INTERNAL_ERROR)
35
+ raise exception
32
36
 
33
37
 
34
38
  def close_connection(conn: Connection) -> None:
@@ -70,17 +74,23 @@ def map_read_jdbc(
70
74
  dbtable = None
71
75
 
72
76
  if not dbtable and not query:
73
- raise ValueError("Include dbtable or query is required option")
77
+ exception = ValueError("Include dbtable or query is required option")
78
+ attach_custom_error_code(exception, ErrorCodes.INSUFFICIENT_INPUT)
79
+ raise exception
74
80
 
75
81
  if query is not None and dbtable is not None:
76
- raise ValueError(
82
+ exception = ValueError(
77
83
  "Not allowed to specify dbtable and query options at the same time"
78
84
  )
85
+ attach_custom_error_code(exception, ErrorCodes.INVALID_INPUT)
86
+ raise exception
79
87
 
80
88
  if query is not None and partition_column is not None:
81
- raise ValueError(
89
+ exception = ValueError(
82
90
  "Not allowed to specify partitionColumn and query options at the same time"
83
91
  )
92
+ attach_custom_error_code(exception, ErrorCodes.INVALID_INPUT)
93
+ raise exception
84
94
 
85
95
  try:
86
96
  df = JdbcDataFrameReader(session, jdbc_options).jdbc_read_dbapi(
@@ -105,4 +115,6 @@ def map_read_jdbc(
105
115
  snowpark_column_types=[f.datatype for f in df.schema.fields],
106
116
  )
107
117
  except Exception as e:
108
- raise Exception(f"Error accessing JDBC datasource for read: {e}")
118
+ exception = Exception(f"Error accessing JDBC datasource for read: {e}")
119
+ attach_custom_error_code(exception, ErrorCodes.INTERNAL_ERROR)
120
+ raise exception
@@ -28,6 +28,8 @@ from snowflake.snowpark.types import (
28
28
  TimestampType,
29
29
  )
30
30
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
31
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
32
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
31
33
  from snowflake.snowpark_connect.relation.read.map_read import JsonReaderConfig
32
34
  from snowflake.snowpark_connect.relation.read.metadata_utils import (
33
35
  add_filename_metadata_to_reader,
@@ -64,9 +66,11 @@ def map_read_json(
64
66
 
65
67
  if rel.read.is_streaming is True:
66
68
  # TODO: Structured streaming implementation.
67
- raise SnowparkConnectNotImplementedError(
69
+ exception = SnowparkConnectNotImplementedError(
68
70
  "Streaming is not supported for JSON files."
69
71
  )
72
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
73
+ raise exception
70
74
  else:
71
75
  snowpark_options = options.convert_to_snowpark_args()
72
76
  raw_options = rel.read.data_source.options
@@ -363,9 +367,11 @@ def construct_row_by_schema(
363
367
  content.get(col_name, None), sf.datatype, snowpark_options
364
368
  )
365
369
  else:
366
- raise SnowparkConnectNotImplementedError(
370
+ exception = SnowparkConnectNotImplementedError(
367
371
  f"JSON construct {str(content)} to StructType failed"
368
372
  )
373
+ attach_custom_error_code(exception, ErrorCodes.TYPE_MISMATCH)
374
+ raise exception
369
375
  return result
370
376
  elif isinstance(schema, ArrayType):
371
377
  result = []
@@ -22,6 +22,8 @@ from snowflake.snowpark._internal.analyzer.analyzer_utils import (
22
22
  from snowflake.snowpark.column import METADATA_FILENAME
23
23
  from snowflake.snowpark.types import DataType, DoubleType, IntegerType, StringType
24
24
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
25
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
26
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
25
27
  from snowflake.snowpark_connect.relation.read.metadata_utils import (
26
28
  add_filename_metadata_to_reader,
27
29
  )
@@ -44,9 +46,11 @@ def map_read_parquet(
44
46
  """Read a Parquet file into a Snowpark DataFrame."""
45
47
 
46
48
  if rel.read.is_streaming is True:
47
- raise SnowparkConnectNotImplementedError(
49
+ exception = SnowparkConnectNotImplementedError(
48
50
  "Streaming is not supported for Parquet files."
49
51
  )
52
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
53
+ raise exception
50
54
 
51
55
  snowpark_options = options.convert_to_snowpark_args()
52
56
  raw_options = rel.read.data_source.options
@@ -155,10 +159,14 @@ def _discover_partition_columns(
155
159
  if i not in dir_level_to_column_name:
156
160
  dir_level_to_column_name[i] = key
157
161
  elif dir_level_to_column_name[i] != key:
158
- raise ValueError(
162
+ exception = ValueError(
159
163
  f"Conflicting partition column names detected: '{dir_level_to_column_name[i]}' and '{key}' "
160
164
  f"at the same directory level"
161
165
  )
166
+ attach_custom_error_code(
167
+ exception, ErrorCodes.INVALID_OPERATION
168
+ )
169
+ raise exception
162
170
 
163
171
  partition_columns_values[key].add(value)
164
172
 
@@ -166,10 +174,12 @@ def _discover_partition_columns(
166
174
  for level in sorted(dir_level_to_column_name.keys()):
167
175
  col_name = dir_level_to_column_name[level]
168
176
  if col_name in seen_columns:
169
- raise ValueError(
177
+ exception = ValueError(
170
178
  f"Found partition column '{col_name}' at multiple directory levels. "
171
179
  f"A partition column can only appear at a single level."
172
180
  )
181
+ attach_custom_error_code(exception, ErrorCodes.INVALID_OPERATION)
182
+ raise exception
173
183
  seen_columns.add(col_name)
174
184
 
175
185
  ordered_columns = [
@@ -9,6 +9,8 @@ import pyspark.sql.connect.proto.relations_pb2 as relation_proto
9
9
 
10
10
  from snowflake import snowpark
11
11
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
12
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
13
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
12
14
  from snowflake.snowpark_connect.utils.telemetry import (
13
15
  SnowparkConnectNotImplementedError,
14
16
  )
@@ -30,7 +32,9 @@ def map_read_socket(
30
32
  host = options.get("host", None)
31
33
  port = options.get("port", None)
32
34
  if not host or not port:
33
- raise ValueError("Host and port must be provided in options.")
35
+ exception = ValueError("Host and port must be provided in options.")
36
+ attach_custom_error_code(exception, ErrorCodes.INVALID_INPUT)
37
+ raise exception
34
38
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
35
39
  try:
36
40
  s.connect((host, int(port)))
@@ -56,8 +60,12 @@ def map_read_socket(
56
60
  snowpark_column_names=[snowpark_cname],
57
61
  )
58
62
  except OSError as e:
59
- raise Exception(f"Error connecting to {host}:{port} - {e}")
63
+ exception = Exception(f"Error connecting to {host}:{port} - {e}")
64
+ attach_custom_error_code(exception, ErrorCodes.INTERNAL_ERROR)
65
+ raise exception
60
66
  else:
61
- raise SnowparkConnectNotImplementedError(
67
+ exception = SnowparkConnectNotImplementedError(
62
68
  "Socket reads are only supported in streaming mode."
63
69
  )
70
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
71
+ raise exception
@@ -18,6 +18,8 @@ from snowflake.snowpark_connect.column_name_handler import (
18
18
  )
19
19
  from snowflake.snowpark_connect.config import auto_uppercase_non_column_identifiers
20
20
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
21
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
22
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
21
23
  from snowflake.snowpark_connect.relation.read.utils import (
22
24
  rename_columns_as_snowflake_standard,
23
25
  )
@@ -64,9 +66,11 @@ def post_process_df(
64
66
  # Check if this is a table/view not found error
65
67
  # Snowflake error codes: 002003 (42S02) - Object does not exist or not authorized
66
68
  if hasattr(e, "sql_error_code") and e.sql_error_code == 2003:
67
- raise AnalysisException(
69
+ exception = AnalysisException(
68
70
  f"[TABLE_OR_VIEW_NOT_FOUND] The table or view cannot be found. {source_table_name}"
69
- ) from None # Suppress original exception to reduce message size
71
+ )
72
+ attach_custom_error_code(exception, ErrorCodes.INTERNAL_ERROR)
73
+ raise exception from None # Suppress original exception to reduce message size
70
74
  # Re-raise if it's not a table not found error
71
75
  raise
72
76
 
@@ -118,9 +122,11 @@ def get_table_from_name(
118
122
 
119
123
  # Verify if recursive view read is not attempted
120
124
  if table_name in get_processed_views():
121
- raise AnalysisException(
125
+ exception = AnalysisException(
122
126
  f"[RECURSIVE_VIEW] Recursive view `{table_name}` detected (cycle: `{table_name}` -> `{table_name}`)"
123
127
  )
128
+ attach_custom_error_code(exception, ErrorCodes.INVALID_OPERATION)
129
+ raise exception
124
130
 
125
131
  snowpark_name = ".".join(
126
132
  quote_name_without_upper_casing(part)
@@ -159,10 +165,14 @@ def map_read_table(
159
165
  and rel.read.data_source.format.lower() == "iceberg"
160
166
  ):
161
167
  if len(rel.read.data_source.paths) != 1:
162
- raise SnowparkConnectNotImplementedError(
168
+ exception = SnowparkConnectNotImplementedError(
163
169
  f"Unexpected paths: {rel.read.data_source.paths}"
164
170
  )
171
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
172
+ raise exception
165
173
  table_identifier = rel.read.data_source.paths[0]
166
174
  else:
167
- raise ValueError("The relation must have a table identifier.")
175
+ exception = ValueError("The relation must have a table identifier.")
176
+ attach_custom_error_code(exception, ErrorCodes.INVALID_INPUT)
177
+ raise exception
168
178
  return get_table_from_name(table_identifier, session, rel.common.plan_id)
@@ -8,6 +8,8 @@ import pyspark.sql.connect.proto.relations_pb2 as relation_proto
8
8
 
9
9
  from snowflake import snowpark
10
10
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
11
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
12
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
11
13
  from snowflake.snowpark_connect.relation.read.utils import (
12
14
  get_spark_column_names_from_snowpark_columns,
13
15
  rename_columns_as_snowflake_standard,
@@ -82,9 +84,11 @@ def map_read_text(
82
84
  """
83
85
  if rel.read.is_streaming is True:
84
86
  # TODO: Structured streaming implementation.
85
- raise SnowparkConnectNotImplementedError(
87
+ exception = SnowparkConnectNotImplementedError(
86
88
  "Streaming is not supported for CSV files."
87
89
  )
90
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
91
+ raise exception
88
92
 
89
93
  df = read_text(paths[0], schema, session, rel.read.data_source.options)
90
94
  if len(paths) > 1:
@@ -16,6 +16,8 @@ from snowflake.snowpark.column import METADATA_FILENAME
16
16
  from snowflake.snowpark.functions import col
17
17
  from snowflake.snowpark.types import StructField
18
18
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
19
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
20
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
19
21
 
20
22
  # Constant for the metadata filename column name
21
23
  METADATA_FILENAME_COLUMN = "METADATA$FILENAME"
@@ -129,9 +131,11 @@ def filter_metadata_columns(
129
131
  if len(non_metadata_columns) == 0:
130
132
  # DataFrame contains only metadata columns (METADATA$FILENAME), no actual data columns remaining.
131
133
  # We don't have a way to return an empty dataframe.
132
- raise AnalysisException(
134
+ exception = AnalysisException(
133
135
  "[DATAFRAME_MISSING_DATA_COLUMNS] Cannot perform operation on DataFrame that contains no data columns."
134
136
  )
137
+ attach_custom_error_code(exception, ErrorCodes.INVALID_OPERATION)
138
+ raise exception
135
139
 
136
140
  filtered_df = result_df.select([col(name) for name in non_metadata_columns])
137
141
 
@@ -11,6 +11,8 @@ from s3fs.core import S3FileSystem
11
11
  from snowflake import snowpark
12
12
  from snowflake.snowpark.session import Session
13
13
  from snowflake.snowpark_connect.config import sessions_config
14
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
15
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
14
16
  from snowflake.snowpark_connect.relation.io_utils import (
15
17
  get_cloud_from_url,
16
18
  parse_azure_url,
@@ -42,9 +44,11 @@ def get_paths_from_stage(
42
44
  rewrite_paths.append(f"{stage_name}/{path}")
43
45
  paths = rewrite_paths
44
46
  case "gcp":
45
- raise AnalysisException(
47
+ exception = AnalysisException(
46
48
  "You must configure an integration for Google Cloud Storage to perform I/O operations rather than accessing the URL directly. Reference: https://docs.snowflake.com/en/user-guide/data-load-gcs-config"
47
49
  )
50
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_OPERATION)
51
+ raise exception
48
52
  case _:
49
53
  filesystem, parsed_path = url_to_fs(paths[0])
50
54
  if isinstance(filesystem, S3FileSystem): # aws
@@ -11,6 +11,8 @@ from snowflake import snowpark
11
11
  from snowflake.snowpark import DataFrameWriter
12
12
  from snowflake.snowpark.dataframe import DataFrame
13
13
  from snowflake.snowpark_connect.dataframe_container import DataFrameContainer
14
+ from snowflake.snowpark_connect.error.error_codes import ErrorCodes
15
+ from snowflake.snowpark_connect.error.error_utils import attach_custom_error_code
14
16
  from snowflake.snowpark_connect.relation.read import jdbc_read_dbapi
15
17
  from snowflake.snowpark_connect.relation.read.jdbc_read_dbapi import JdbcDialect
16
18
  from snowflake.snowpark_connect.relation.read.utils import Connection
@@ -65,9 +67,13 @@ class JdbcDataFrameWriter(DataFrameWriter):
65
67
  self._create_table(conn, table, container, jdbc_dialect)
66
68
  case "errorifexists":
67
69
  if table_exist:
68
- raise ValueError(
70
+ exception = ValueError(
69
71
  "table is already exist and write mode is ERROR_IF_EXISTS"
70
72
  )
73
+ attach_custom_error_code(
74
+ exception, ErrorCodes.INVALID_OPERATION
75
+ )
76
+ raise exception
71
77
  else:
72
78
  self._create_table(conn, table, container, jdbc_dialect)
73
79
  case "overwrite":
@@ -82,7 +88,9 @@ class JdbcDataFrameWriter(DataFrameWriter):
82
88
  else:
83
89
  self._create_table(conn, table, container, jdbc_dialect)
84
90
  case _:
85
- raise ValueError(f"Invalid write mode value{write_mode}")
91
+ exception = ValueError(f"Invalid write mode value{write_mode}")
92
+ attach_custom_error_code(exception, ErrorCodes.INVALID_INPUT)
93
+ raise exception
86
94
 
87
95
  task_insert_into_data_source_with_retry(
88
96
  input_df,
@@ -141,6 +149,7 @@ class JdbcDataFrameWriter(DataFrameWriter):
141
149
  cursor.execute(sql)
142
150
  except Exception as e:
143
151
  logger.error(f"failed to drop table {table} from the data source {e}")
152
+ attach_custom_error_code(e, ErrorCodes.INTERNAL_ERROR)
144
153
  raise e
145
154
 
146
155
  def _create_table(
@@ -189,6 +198,7 @@ class JdbcDataFrameWriter(DataFrameWriter):
189
198
  cursor.execute(sql)
190
199
  except Exception as e:
191
200
  logger.error(f"failed to create a table {table} from the data source {e}")
201
+ attach_custom_error_code(e, ErrorCodes.INTERNAL_ERROR)
192
202
  raise e
193
203
 
194
204
 
@@ -218,6 +228,7 @@ def _task_insert_into_data_source(
218
228
  except Exception as e:
219
229
  logger.debug(f"failed to insert into data source {e}")
220
230
  conn.rollback()
231
+ attach_custom_error_code(e, ErrorCodes.INTERNAL_ERROR)
221
232
  raise e
222
233
  finally:
223
234
  cursor.close()
@@ -274,6 +285,7 @@ def task_insert_into_data_source_with_retry(
274
285
  )
275
286
  except Exception as e:
276
287
  logger.debug(f"failed to insert into data source {e}")
288
+ attach_custom_error_code(e, ErrorCodes.INTERNAL_ERROR)
277
289
  raise e
278
290
  finally:
279
291
  close_connection(conn)
@@ -339,4 +351,8 @@ def convert_sp_to_sql_type(
339
351
  case _:
340
352
  return "TIMESTAMP"
341
353
  case _:
342
- raise TypeError(f"Unsupported data type: {datatype.__class__.__name__}")
354
+ exception = TypeError(
355
+ f"Unsupported data type: {datatype.__class__.__name__}"
356
+ )
357
+ attach_custom_error_code(exception, ErrorCodes.UNSUPPORTED_TYPE)
358
+ raise exception