Skip to content

Commit 1db7aa3

Browse files
committed
refactor: improve error handling, parameter validation, and logging in Spanner DBAPI driver
1 parent 78aa052 commit 1db7aa3

File tree

6 files changed

+37
-36
lines changed

6 files changed

+37
-36
lines changed

packages/google-cloud-spanner-dbapi-driver/google/cloud/spanner_driver/__init__.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,32 +52,32 @@
5252
logger.addHandler(logging.NullHandler())
5353

5454
__all__: list[str] = [
55-
"apilevel",
56-
"threadsafety",
57-
"paramstyle",
55+
"BINARY",
56+
"Binary",
5857
"Connection",
59-
"connect",
6058
"Cursor",
61-
"Date",
62-
"Time",
63-
"Timestamp",
64-
"DateFromTicks",
65-
"TimeFromTicks",
66-
"TimestampFromTicks",
67-
"Binary",
68-
"STRING",
69-
"BINARY",
70-
"NUMBER",
7159
"DATETIME",
72-
"ROWID",
73-
"InterfaceError",
74-
"ProgrammingError",
75-
"OperationalError",
76-
"DatabaseError",
7760
"DataError",
78-
"NotSupportedError",
61+
"DatabaseError",
62+
"Date",
63+
"DateFromTicks",
64+
"Error",
7965
"IntegrityError",
66+
"InterfaceError",
8067
"InternalError",
68+
"NUMBER",
69+
"NotSupportedError",
70+
"OperationalError",
71+
"ProgrammingError",
72+
"ROWID",
73+
"STRING",
74+
"Time",
75+
"TimeFromTicks",
76+
"Timestamp",
77+
"TimestampFromTicks",
8178
"Warning",
82-
"Error",
79+
"apilevel",
80+
"connect",
81+
"paramstyle",
82+
"threadsafety",
8383
]

packages/google-cloud-spanner-dbapi-driver/google/cloud/spanner_driver/connection.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ def commit(self) -> None:
8989
try:
9090
self._internal_conn.commit()
9191
except Exception as e:
92-
# raise errors.map_spanner_error(e)
9392
logger.debug(f"Commit failed {e}")
93+
raise errors.map_spanner_error(e)
9494

9595
@check_not_closed
9696
def rollback(self) -> None:
@@ -102,8 +102,8 @@ def rollback(self) -> None:
102102
try:
103103
self._internal_conn.rollback()
104104
except Exception as e:
105-
# raise errors.map_spanner_error(e)
106105
logger.debug(f"Rollback failed {e}")
106+
raise errors.map_spanner_error(e)
107107

108108
def close(self) -> None:
109109
"""Close the connection now.
@@ -127,7 +127,7 @@ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
127127
self.close()
128128

129129

130-
def connect(connection_string: str, **kwargs: Any) -> Connection:
130+
def connect(connection_string: str) -> Connection:
131131
logger.debug(f"Connecting to {connection_string}")
132132
# Create the pool
133133
pool = Pool.create_pool(connection_string)

packages/google-cloud-spanner-dbapi-driver/google/cloud/spanner_driver/cursor.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def description(self) -> tuple[tuple[Any, ...], ...] | None:
116116
)
117117
)
118118
return tuple(desc)
119-
except Exception:
119+
except Exception as e:
120+
logger.warning("Could not determine cursor description: %s", e)
120121
return None
121122

122123
@property
@@ -165,8 +166,9 @@ def _prepare_params(
165166
# GoogleSQL Dialect: Named parameters @name are mapped directly.
166167
iterator = parameters.items()
167168
else:
168-
# If strictly required, raise an error for unsupported types
169-
return {}, {}
169+
raise errors.ProgrammingError(
170+
f"Parameters must be a dict, list, or tuple, not {type(parameters).__name__}"
171+
)
170172

171173
for key, value in iterator:
172174
if value is None:
@@ -429,7 +431,8 @@ def nextset(self) -> bool | None:
429431
if next_metadata:
430432
return True
431433
return None
432-
except Exception:
434+
except Exception as e:
435+
logger.warning("Could not determine next set of results: %s", e)
433436
return None
434437

435438
def __enter__(self) -> "Cursor":

packages/google-cloud-spanner-dbapi-driver/tests/system/test_cursor.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,3 @@ def test_data_types(self):
141141
assert row[2] is True
142142
assert row[3] == "hello"
143143
assert row[4] == b"bytes"
144-
assert row[4] == b"bytes"

packages/google-cloud-spanner-dbapi-driver/tests/unit/test_connection.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,18 @@ def test_commit(self):
7070

7171
def test_commit_error(self):
7272
self.mock_internal_conn.commit.side_effect = Exception("Commit Failed")
73-
try:
73+
with self.assertRaises(errors.DatabaseError):
7474
self.conn.commit()
75-
except Exception:
76-
self.fail("commit() raised Exception unexpectedly!")
7775
self.mock_internal_conn.commit.assert_called_once()
7876

7977
def test_rollback(self):
8078
self.conn.rollback()
8179
self.mock_internal_conn.rollback.assert_called_once()
8280

8381
def test_rollback_error(self):
84-
# Similar to commit, rollback errors are caught and logged
8582
self.mock_internal_conn.rollback.side_effect = Exception("Rollback Failed")
86-
try:
83+
with self.assertRaises(errors.DatabaseError):
8784
self.conn.rollback()
88-
except Exception:
89-
self.fail("rollback() raised Exception unexpectedly!")
9085
self.mock_internal_conn.rollback.assert_called_once()
9186

9287
def test_close(self):

packages/google-cloud-spanner-dbapi-driver/tests/unit/test_cursor.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,7 @@ def test_prepare_params(self):
347347

348348
self.assertEqual(converted["P2"], "test")
349349
self.assertEqual(types["P2"].code, TypeCode.STRING)
350+
351+
def test_prepare_params_unsupported_type(self):
352+
with self.assertRaises(cursor.errors.ProgrammingError):
353+
self.cursor._prepare_params(123) # Int is not supported directly

0 commit comments

Comments
 (0)