Skip to content

Commit bbd049f

Browse files
authoredFeb 2, 2024
Support error packet without sqlstate (#1160)
Fix #1156
1 parent 9694747 commit bbd049f

File tree

4 files changed

+22
-13
lines changed

4 files changed

+22
-13
lines changed
 

Diff for: ‎pymysql/connections.py

-2
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,6 @@ def _read_packet(self, packet_type=MysqlPacket):
765765
dump_packet(recv_data)
766766
buff += recv_data
767767
# https://dev.mysql.com/doc/internals/en/sending-more-than-16mbyte.html
768-
if bytes_to_read == 0xFFFFFF:
769-
continue
770768
if bytes_to_read < MAX_PACKET_LEN:
771769
break
772770

Diff for: ‎pymysql/err.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,14 @@ def _map_error(exc, *errors):
136136

137137
def raise_mysql_exception(data):
138138
errno = struct.unpack("<h", data[1:3])[0]
139-
errval = data[9:].decode("utf-8", "replace")
139+
# https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_err_packet.html
140+
# Error packet has optional sqlstate that is 5 bytes and starts with '#'.
141+
if data[3] == 0x23: # '#'
142+
# sqlstate = data[4:9].decode()
143+
# TODO: Append (sqlstate) in the error message. This will be come in next minor release.
144+
errval = data[9:].decode("utf-8", "replace")
145+
else:
146+
errval = data[3:].decode("utf-8", "replace")
140147
errorclass = error_map.get(errno)
141148
if errorclass is None:
142149
errorclass = InternalError if errno < 1000 else OperationalError

Diff for: ‎pymysql/tests/test_err.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import unittest
2-
1+
import pytest
32
from pymysql import err
43

54

6-
__all__ = ["TestRaiseException"]
7-
5+
def test_raise_mysql_exception():
6+
data = b"\xff\x15\x04#28000Access denied"
7+
with pytest.raises(err.OperationalError) as cm:
8+
err.raise_mysql_exception(data)
9+
assert cm.type == err.OperationalError
10+
assert cm.value.args == (1045, "Access denied")
811

9-
class TestRaiseException(unittest.TestCase):
10-
def test_raise_mysql_exception(self):
11-
data = b"\xff\x15\x04#28000Access denied"
12-
with self.assertRaises(err.OperationalError) as cm:
13-
err.raise_mysql_exception(data)
14-
self.assertEqual(cm.exception.args, (1045, "Access denied"))
12+
data = b"\xff\x10\x04Too many connections"
13+
with pytest.raises(err.OperationalError) as cm:
14+
err.raise_mysql_exception(data)
15+
assert cm.type == err.OperationalError
16+
assert cm.value.args == (1040, "Too many connections")

Diff for: ‎pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ version = {attr = "pymysql.VERSION_STRING"}
5656
exclude = [
5757
"pymysql/tests/thirdparty",
5858
]
59+
60+
[tool.ruff.lint]
5961
ignore = ["E721"]
6062

6163
[tool.pdm.dev-dependencies]

0 commit comments

Comments
 (0)
Please sign in to comment.