Added more detailed error handling

namely being able to detect conflicts and bad requests
This commit is contained in:
Honza Král
2013-11-14 01:12:55 +01:00
parent 62738c85c4
commit 4bce8a464c
3 changed files with 40 additions and 7 deletions
+13 -1
View File
@@ -1,4 +1,7 @@
__all__ = ['ImproperlyConfigured', 'ElasticsearchException', 'SerializationError', 'TransportError', 'NotFoundError'] __all__ = [
'ImproperlyConfigured', 'ElasticsearchException', 'SerializationError',
'TransportError', 'NotFoundError', 'ConflictError', 'RequestError'
]
class ImproperlyConfigured(Exception): class ImproperlyConfigured(Exception):
pass pass
@@ -43,7 +46,16 @@ class NotFoundError(TransportError):
pass pass
class ConflictError(TransportError):
pass
class RequestError(TransportError):
pass
# more generic mappings from status_code to python exceptions # more generic mappings from status_code to python exceptions
HTTP_EXCEPTIONS = { HTTP_EXCEPTIONS = {
400: RequestError,
404: NotFoundError, 404: NotFoundError,
409: ConflictError,
} }
+13 -1
View File
@@ -2,7 +2,7 @@ import re
from mock import Mock, patch from mock import Mock, patch
import urllib3 import urllib3
from elasticsearch.exceptions import TransportError from elasticsearch.exceptions import TransportError, ConflictError, RequestError, NotFoundError
from elasticsearch.connection import RequestsHttpConnection, \ from elasticsearch.connection import RequestsHttpConnection, \
Urllib3HttpConnection, THRIFT_AVAILABLE, ThriftConnection Urllib3HttpConnection, THRIFT_AVAILABLE, ThriftConnection
@@ -96,6 +96,18 @@ class TestRequestsConnection(TestCase):
con = self._get_mock_connection({"host": "elasticsearch.com", "port": 443}) con = self._get_mock_connection({"host": "elasticsearch.com", "port": 443})
self.assertEquals('<RequestsHttpConnection: http://elasticsearch.com:443>', repr(con)) self.assertEquals('<RequestsHttpConnection: http://elasticsearch.com:443>', repr(con))
def test_conflict_error_is_returned_on_409(self):
con = self._get_mock_connection(status_code=409)
self.assertRaises(ConflictError, con.perform_request, 'GET', '/', {}, '')
def test_not_found_error_is_returned_on_404(self):
con = self._get_mock_connection(status_code=404)
self.assertRaises(NotFoundError, con.perform_request, 'GET', '/', {}, '')
def test_request_error_is_returned_on_400(self):
con = self._get_mock_connection(status_code=400)
self.assertRaises(RequestError, con.perform_request, 'GET', '/', {}, '')
@patch('elasticsearch.connection.base.tracer') @patch('elasticsearch.connection.base.tracer')
@patch('elasticsearch.connection.base.logger') @patch('elasticsearch.connection.base.logger')
def test_failed_request_logs_and_traces(self, logger, tracer): def test_failed_request_logs_and_traces(self, logger, tracer):
+14 -5
View File
@@ -7,6 +7,8 @@ from os import walk, environ
from os.path import exists, join, dirname, pardir from os.path import exists, join, dirname, pardir
import yaml import yaml
from elasticsearch import TransportError
from ..test_cases import SkipTest from ..test_cases import SkipTest
from . import ElasticTestCase from . import ElasticTestCase
@@ -14,11 +16,16 @@ from . import ElasticTestCase
# those in the tests accordingly # those in the tests accordingly
PARAMS_RENAMES = { PARAMS_RENAMES = {
'type': 'doc_type', 'type': 'doc_type',
'from': 'offset', 'from': 'from_',
} }
ES_VERSION = None ES_VERSION = None
# mapping from catch values to http status codes
CATCH_CODES = {
'missing': 404,
'conflict': 409,
}
class InvalidActionType(Exception): class InvalidActionType(Exception):
pass pass
@@ -105,10 +112,10 @@ class YamlTestCase(ElasticTestCase):
try: try:
self.last_response = api(**args) self.last_response = api(**args)
except: except Exception as e:
if not catch: if not catch:
raise raise
self.run_catch(catch) self.run_catch(catch, e)
else: else:
if catch: if catch:
raise AssertionError('Failed to catch %r in %r.' % (catch, self.last_response)) raise AssertionError('Failed to catch %r in %r.' % (catch, self.last_response))
@@ -122,8 +129,10 @@ class YamlTestCase(ElasticTestCase):
raise SkipTest(reason) raise SkipTest(reason)
def run_catch(self, catch): def run_catch(self, catch, exception):
pass self.assertIsInstance(exception, TransportError)
if catch in CATCH_CODES:
self.assertEquals(CATCH_CODES[catch], exception.status_code)
def run_gt(self, action): def run_gt(self, action):
for key, value in action.items(): for key, value in action.items():