Fix ECDriverError.__str__

If ECDriverError is initialized with a non-string argument then its
str method returns non-string, it will return a confusable message
for users.

This patch fixes ECDriverError to set a string message when
the argument doesn't have str method which return a string.
This commit is contained in:
Kota Tsuyuzaki 2015-04-01 21:26:06 -07:00
parent 9b2ed408c1
commit 132683ba8c
2 changed files with 49 additions and 3 deletions

View File

@ -112,8 +112,12 @@ class PyECLib_FRAGHDRCHKSUM_Types(PyECLibEnum):
# Generic ECDriverException
class ECDriverError(Exception):
def __init__(self, error_str):
self.error_str = error_str
def __init__(self, error):
try:
self.error_str = str(error)
except TypeError:
self.error_str = 'Error retrieving the error message from %s' \
% error.__class__.__name__
def __str__(self):
return self.error_str

View File

@ -26,12 +26,14 @@ from string import ascii_letters, ascii_uppercase, digits
import sys
import tempfile
import unittest
import mock
from pyeclib.ec_iface import ECDriverError
from pyeclib.ec_iface import ECDriver, VALID_EC_TYPES, ECDriverError, \
PyECLib_EC_Types
from test_pyeclib_c import _available_backends
import pyeclib_c
from pyeclib_c import error as PyECLibError
if sys.version < '3':
def b2i(b):
@ -207,7 +209,7 @@ class TestPyECLibDriver(unittest.TestCase):
def test_get_metadata_formatted(self):
pyeclib_driver = ECDriver(k=12, m=2, ec_type="jerasure_rs_vand", chksum_type="inline_crc32")
filesize = 1024 * 1024 * 3
file_str = ''.join(random.choice(ascii_letters) for i in range(filesize))
file_bytes = file_str.encode('utf-8')
@ -547,5 +549,45 @@ class TestPyECLibDriver(unittest.TestCase):
self.assertTrue(
pyeclib_drivers[0].min_parity_fragments_needed() == 1)
def test_ECDriver_error_handling(self):
driver = ECDriver(k=3, m=1, ec_type="jerasure_rs_vand")
class MockPyECLibError(PyECLibError):
def __str__(self):
return mock.MagicMock()
with mock.patch('pyeclib_c.decode', side_effect=MockPyECLibError()):
with self.assertRaises(ECDriverError) as cm:
driver.decode([' ' for x in xrange(4)])
exception = cm.exception
expected = 'Error retrieving the error message from MockPyECLibError'
self.assertEquals(expected, str(exception))
def test_ECDriverError_init(self):
class mock_class(object):
def __init__(self, return_str):
self.return_str = return_str
def __str__(self):
if self.return_str:
return 'message'
else:
return mock.MagicMock()
# init with str
error = ECDriverError('message')
self.assertEquals('message', str(error))
# init with instance with valid __str__
error = ECDriverError(mock_class(True))
self.assertEquals('message', str(error))
# init with instance with invalid __str__
error = ECDriverError(mock_class(False))
self.assertEquals('Error retrieving the error message from mock_class',
str(error))
if __name__ == '__main__':
unittest.main()