Fix parsing of server errors in ClickHouse v19.3.3+

This commit is contained in:
Itai Shirav 2019-02-26 22:46:00 +02:00
parent af3bdb3ff2
commit bec45b53fa
3 changed files with 51 additions and 9 deletions

View File

@ -4,6 +4,7 @@ Change Log
Unreleased Unreleased
---------- ----------
- Extend date field range (trthhrtz) - Extend date field range (trthhrtz)
- Fix parsing of server errors in ClickHouse v19.3.3+
v1.0.4 v1.0.4
------ ------

View File

@ -40,11 +40,19 @@ class ServerError(DatabaseException):
self.message = message self.message = message
super(ServerError, self).__init__(message) super(ServerError, self).__init__(message)
ERROR_PATTERN = re.compile(r''' ERROR_PATTERNS = (
Code:\ (?P<code>\d+), # ClickHouse prior to v19.3.3
\ e\.displayText\(\)\ =\ (?P<type1>[^ \n]+):\ (?P<msg>.+?), re.compile(r'''
\ e.what\(\)\ =\ (?P<type2>[^ \n]+) Code:\ (?P<code>\d+),
''', re.VERBOSE | re.DOTALL) \ e\.displayText\(\)\ =\ (?P<type1>[^ \n]+):\ (?P<msg>.+?),
\ e.what\(\)\ =\ (?P<type2>[^ \n]+)
''', re.VERBOSE | re.DOTALL),
# ClickHouse v19.3.3+
re.compile(r'''
Code:\ (?P<code>\d+),
\ e\.displayText\(\)\ =\ (?P<type1>[^ \n]+):\ (?P<msg>.+)
''', re.VERBOSE | re.DOTALL),
)
@classmethod @classmethod
def get_error_code_msg(cls, full_error_message): def get_error_code_msg(cls, full_error_message):
@ -54,10 +62,11 @@ class ServerError(DatabaseException):
See the list of error codes here: See the list of error codes here:
https://github.com/yandex/ClickHouse/blob/master/dbms/src/Common/ErrorCodes.cpp https://github.com/yandex/ClickHouse/blob/master/dbms/src/Common/ErrorCodes.cpp
""" """
match = cls.ERROR_PATTERN.match(full_error_message) for pattern in cls.ERROR_PATTERNS:
if match: match = pattern.match(full_error_message)
# assert match.group('type1') == match.group('type2') if match:
return int(match.group('code')), match.group('msg') # assert match.group('type1') == match.group('type2')
return int(match.group('code')), match.group('msg').strip()
return 0, full_error_message return 0, full_error_message

View File

@ -0,0 +1,32 @@
from __future__ import unicode_literals
import unittest
from infi.clickhouse_orm.database import ServerError
class ServerErrorTest(unittest.TestCase):
def test_old_format(self):
code, msg = ServerError.get_error_code_msg("Code: 81, e.displayText() = DB::Exception: Database db_not_here doesn't exist, e.what() = DB::Exception (from [::1]:33458)")
self.assertEquals(code, 81)
self.assertEquals(msg, "Database db_not_here doesn't exist")
code, msg = ServerError.get_error_code_msg("Code: 161, e.displayText() = DB::Exception: Limit for number of columns to read exceeded. Requested: 11, maximum: 1, e.what() = DB::Exception\n")
self.assertEquals(code, 161)
self.assertEquals(msg, "Limit for number of columns to read exceeded. Requested: 11, maximum: 1")
def test_new_format(self):
code, msg = ServerError.get_error_code_msg("Code: 164, e.displayText() = DB::Exception: Cannot drop table in readonly mode")
self.assertEquals(code, 164)
self.assertEquals(msg, "Cannot drop table in readonly mode")
code, msg = ServerError.get_error_code_msg("Code: 48, e.displayText() = DB::Exception: Method write is not supported by storage Merge")
self.assertEquals(code, 48)
self.assertEquals(msg, "Method write is not supported by storage Merge")
code, msg = ServerError.get_error_code_msg("Code: 60, e.displayText() = DB::Exception: Table default.zuzu doesn't exist.\n")
self.assertEquals(code, 60)
self.assertEquals(msg, "Table default.zuzu doesn't exist.")