Skip to content

Commit bbd049f

Browse files
authored
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

pymysql/connections.py

Lines changed: 0 additions & 2 deletions
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

pymysql/err.py

Lines changed: 8 additions & 1 deletion
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

pymysql/tests/test_err.py

Lines changed: 12 additions & 10 deletions
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")

pyproject.toml

Lines changed: 2 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy