Skip to content

Commit e4e3884

Browse files
committed
Replace postgresql error parser
1 parent b593b61 commit e4e3884

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

aurora_data_api/__init__.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636

3737
logger = logging.getLogger(__name__)
3838

39-
postgresql_error_reg = re.compile(r'^ERROR:\s(.*)\s(?:[\s+]+Position:\s([0-9]+);\s)?SQLState:\s([0-9A-Z]+)$')
40-
4139

4240
class AuroraDataAPIClient:
4341
def __init__(self, dbname=None, aurora_cluster_arn=None, secret_arn=None, rds_data_client=None, charset=None,
@@ -212,18 +210,24 @@ def _prepare_execute_args(self, operation):
212210
def _format_parameter_set(self, parameters):
213211
return [self.prepare_param(k, v) for k, v in parameters.items()]
214212

215-
def _get_database_error(self, origin_error):
216-
error_msg = getattr(origin_error, "response", {}).get("Error", {}).get("Message", "")
213+
def _get_database_error(self, original_error):
214+
error_msg = getattr(original_error, "response", {}).get("Error", {}).get("Message", "")
217215
try:
218216
if error_msg.startswith("Database error code"): # MySQL error
219217
code, msg = (s.split(": ", 1)[1] for s in error_msg.split(". ", 1))
220-
return DatabaseError(MySQLErrorCodes(int(code)), msg)
221-
elif error_msg.startswith("ERROR: "): # Postgresql error
222-
msg, pos, code = postgresql_error_reg.match(error_msg.replace('\n', '')).groups()
223-
return DatabaseError(PostgreSQLErrorCodes(code), msg, pos)
218+
mysql_error_code = MySQLErrorCodes(int(code))
219+
return DatabaseError(mysql_error_code, msg)
220+
elif error_msg.startswith("ERROR: "): # PostgreSQL error
221+
error_msg = error_msg[len("ERROR: "):]
222+
error_lines = error_msg.splitlines()
223+
if error_lines[-1].startswith(" Position: ") and " SQLState: " in error_lines[-1]:
224+
position, sqlstate = (i.split(":", 1)[1].strip() for i in error_lines[-1].strip().split(";"))
225+
postgres_error_code = PostgreSQLErrorCodes(sqlstate)
226+
return DatabaseError(postgres_error_code, "\n".join(error_lines[:-1]), int(position))
227+
raise Exception("unable to parse postgresql error")
224228
except Exception:
225229
pass
226-
return DatabaseError(origin_error)
230+
return DatabaseError(original_error)
227231

228232
def execute(self, operation, parameters=None):
229233
self._current_response, self._iterator, self._paging_state = None, None, None

test/test.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import os, sys, json, unittest, logging, uuid, decimal, datetime
1+
import os, sys, json, unittest, logging, uuid, decimal, datetime, time
22

33
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
44

55
import aurora_data_api # noqa
66
from aurora_data_api.mysql_error_codes import MySQLErrorCodes # noqa
7+
from aurora_data_api.postgresql_error_codes import PostgreSQLErrorCodes # noqa
78

89
logging.basicConfig(level=logging.INFO)
910
logging.getLogger("aurora_data_api").setLevel(logging.DEBUG)
@@ -136,6 +137,18 @@ def test_pagination_backoff(self):
136137
"Database response exceeded size limit"):
137138
cur.fetchall()
138139

140+
def test_postgres_exceptions(self):
141+
if self.using_mysql:
142+
return
143+
with aurora_data_api.connect(database=self.db_name) as conn, conn.cursor() as cur:
144+
table = "aurora_data_api_nonexistent_test_table"
145+
with self.assertRaises(aurora_data_api.DatabaseError) as e:
146+
sql = f"select * from {table}"
147+
cur.execute(sql)
148+
self.assertEqual(e.exception.args, (PostgreSQLErrorCodes.ER_UNDEF_TABLE,
149+
f'relation "{table}" does not exist',
150+
15))
151+
139152
def test_rowcount(self):
140153
with aurora_data_api.connect(database=self.db_name) as conn, conn.cursor() as cur:
141154
cur.execute("select * from aurora_data_api_test limit 8")

0 commit comments

Comments
 (0)