Files
2025-09-29 00:52:08 +02:00

227 lines
9.3 KiB
Python
Executable File

# MySQL Connector/Python - MySQL driver written in Python.
# Copyright (c) 2009,2010, Oracle and/or its affiliates. All rights reserved.
# Use is subject to license terms. (See COPYING)
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# There are special exceptions to the terms and conditions of the GNU
# General Public License as it is applied to this software. View the
# full text of the exception in file EXCEPTIONS-CLIENT in the directory
# of this software distribution or see the FOSS License Exception at
# www.mysql.com.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Python exceptions
"""
import logging
import utils
logger = logging.getLogger('myconnpy')
# see get_mysql_exceptions method for errno ranges and smaller lists
__programming_errors = (
1083,1084,1090,1091,1093,1096,1097,1101,1102,1103,1107,1108,1110,1111,
1113,1120,1124,1125,1128,1136,1366,1139,1140,1146,1149,)
__operational_errors = (
1028,1029,1030,1053,1077,1078,1079,1080,1081,1095,1104,1106,1114,1116,
1117,1119,1122,1123,1126,1133,1135,1137,1145,1147,)
def get_mysql_exception(errno,msg):
exception = OperationalError
if (errno >= 1046 and errno <= 1052) or \
(errno >= 1054 and errno <= 1061) or \
(errno >= 1063 and errno <= 1075) or \
errno in __programming_errors:
exception = ProgrammingError
elif errno in (1097,1109,1118,1121,1138,1292):
exception = DataError
elif errno in (1031,1089,1112,1115,1127,1148,1149):
exception = NotSupportedError
elif errno in (1062,1082,1099,1100):
exception = IntegrityError
elif errno in (1085,1086,1094,1098):
exception = InternalError
elif (errno >= 1004 and errno <= 1030) or \
(errno >= 1132 and errno <= 1045) or \
(errno >= 1141 and errno <= 1145) or \
(errno >= 1129 and errno <= 1133) or \
errno in __operational_errors:
exception = OperationalError
return exception(msg,errno=errno)
def raise_error(buf):
"""Raise an errors.Error when buffer has a MySQL error"""
errno = errmsg = None
try:
buf = buf[5:]
(buf,errno) = utils.read_int(buf, 2)
if buf[0] != '\x23':
# Error without SQLState
errmsg = buf
else:
(buf,sqlstate) = utils.read_bytes(buf[1:],5)
errmsg = buf
except Exception, e:
raise InterfaceError("Failed getting Error information (%r)"\
% e)
else:
raise get_mysql_exception(errno,errmsg)
class ClientError(object):
client_errors = {
2000: "Unknown MySQL error",
2001: "Can't create UNIX socket (%(socketaddr)d)",
2002: "Can't connect to local MySQL server through socket '%(socketaddr)s' (%(errno)s)",
2003: "Can't connect to MySQL server on '%(socketaddr)s' (%(errno)s)",
2004: "Can't create TCP/IP socket (%s)",
2005: "Unknown MySQL server host '%(socketaddr)s' (%s)",
2006: "MySQL server has gone away",
2007: "Protocol mismatch; server version = %(server_version)d, client version = %(client_version)d",
2008: "MySQL client ran out of memory",
2009: "Wrong host info",
2010: "Localhost via UNIX socket",
2011: "%(misc)s via TCP/IP",
2012: "Error in server handshake",
2013: "Lost connection to MySQL server during query",
2014: "Commands out of sync; you can't run this command now",
2015: "Named pipe: %(socketaddr)s",
2016: "Can't wait for named pipe to host: %(host)s pipe: %(socketaddr)s (%(errno)d)",
2017: "Can't open named pipe to host: %s pipe: %s (%(errno)d)",
2018: "Can't set state of named pipe to host: %(host)s pipe: %(socketaddr)s (%(errno)d)",
2019: "Can't initialize character set %(charset)s (path: %(misc)s)",
2020: "Got packet bigger than 'max_allowed_packet' bytes",
2021: "Embedded server",
2022: "Error on SHOW SLAVE STATUS:",
2023: "Error on SHOW SLAVE HOSTS:",
2024: "Error connecting to slave:",
2025: "Error connecting to master:",
2026: "SSL connection error",
2027: "Malformed packet",
2028: "This client library is licensed only for use with MySQL servers having '%s' license",
2029: "Invalid use of null pointer",
2030: "Statement not prepared",
2031: "No data supplied for parameters in prepared statement",
2032: "Data truncated",
2033: "No parameters exist in the statement",
2034: "Invalid parameter number",
2035: "Can't send long data for non-string/non-binary data types (parameter: %d)",
2036: "Using unsupported buffer type: %d (parameter: %d)",
2037: "Shared memory: %s",
2038: "Can't open shared memory; client could not create request event (%d)",
2039: "Can't open shared memory; no answer event received from server (%d)",
2040: "Can't open shared memory; server could not allocate file mapping (%d)",
2041: "Can't open shared memory; server could not get pointer to file mapping (%d)",
2042: "Can't open shared memory; client could not allocate file mapping (%d)",
2043: "Can't open shared memory; client could not get pointer to file mapping (%d)",
2044: "Can't open shared memory; client could not create %s event (%d)",
2045: "Can't open shared memory; no answer from server (%d)",
2046: "Can't open shared memory; cannot send request event to server (%d)",
2047: "Wrong or unknown protocol",
2048: "Invalid connection handle",
2049: "Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
2050: "Row retrieval was canceled by mysql_stmt_close() call",
2051: "Attempt to read column without prior row fetch",
2052: "Prepared statement contains no metadata",
2053: "Attempt to read a row while there is no result set associated with the statement",
2054: "This feature is not implemented yet",
2055: "Lost connection to MySQL server at '%(socketaddr)s', system error: %(errno)d",
2056: "Statement closed indirectly because of a preceeding %s() call",
2057: "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
}
def __new__(cls):
raise TypeError, "Can not instanciate from %s" % cls.__name__
@classmethod
def get_error_msg(cls,errno,values=None):
res = None
if cls.client_errors.has_key(errno):
if values is not None:
try:
res = cls.client_errors[errno] % values
except:
logger.debug("Missing values for errno %d" % errno)
res = cls.client_errors[errno], "(missing values!)"
else:
res = cls.client_errors[errno]
if res is None:
res = "Unknown client error %d" % errno
logger.debug(res)
return res
class Error(StandardError):
def __init__(self, m, errno=None, values=None):
try:
# process MySQL error packet
self._process_packet(m)
except:
self.errno = errno or -1
self.sqlstate = -1
if m is None and (errno >= 2000 and errno < 3000):
m = ClientError.get_error_msg(errno,values)
elif m is None:
m = 'Unknown error'
if self.errno != -1:
self.msg = "%s: %s" % (self.errno,m)
else:
self.msg = m
def _process_packet(self, packet):
self.errno = packet.errno
self.sqlstate = packet.sqlstate
if self.sqlstate:
self.msg = '%d (%s): %s' % (self.errno,self.sqlstate,packet.errmsg)
else:
self.msg = '%d: %s' % (self.errno, packet.errmsg)
def __str__(self):
return self.msg
def __unicode__(self):
return self.msg
class Warning(StandardError):
pass
class InterfaceError(Error):
def __init__(self, m=None, errno=None, values=None):
Error.__init__(self, m, errno, values)
class DatabaseError(Error):
def __init__(self, m=None, errno=None, values=None):
Error.__init__(self, m, errno, values)
class InternalError(DatabaseError):
pass
class OperationalError(DatabaseError):
pass
class ProgrammingError(DatabaseError):
pass
class IntegrityError(DatabaseError):
pass
class DataError(DatabaseError):
pass
class NotSupportedError(DatabaseError):
pass