def _raise_for_status(self, response): """ make sure that only crate.exceptions are raised that are defined in the DB-API specification """ http_error_msg = '' if 400 <= response.status < 500: http_error_msg = '%s Client Error: %s' % ( response.status, response.reason) elif 500 <= response.status < 600: http_error_msg = '%s Server Error: %s' % ( response.status, response.reason) else: return if response.status == 503: raise ConnectionError(http_error_msg) if response.headers.get("content-type", "" ).startswith("application/json"): data = json.loads(six.text_type(response.data, 'utf-8')) error = data.get('error', {}) error_trace = data.get('error_trace', None) if "results" in data: errors = [res["error_message"] for res in data["results"] if res.get("error_message")] if errors: raise ProgrammingError("\n".join(errors)) if isinstance(error, dict): raise ProgrammingError(error.get('message', ''), error_trace=error_trace) raise ProgrammingError(error, error_trace=error_trace) raise ProgrammingError(http_error_msg)
def _json_from_response(response): try: return json.loads(response.data.decode('utf-8')) except ValueError: raise ProgrammingError( "Invalid server response of content-type '{}':\n{}" .format(response.headers.get("content-type", "unknown"), response.data.decode('utf-8')))
def _json_from_response(response): try: return json.loads(six.text_type(response.data, 'utf-8')) except ValueError: raise ProgrammingError( "Invalid server response of content-type '%s'" % response.headers.get("content-type", "unknown"))
def test_verbose_no_error_trace(self): with CrateShell(error_trace=True) as cmd: cmd.logger = Mock() cmd.cursor.execute = Mock(side_effect=ProgrammingError( msg="the error message", error_trace=None)) cmd.execute("select invalid statement") # only the message is logged cmd.logger.critical.assert_called_once_with("the error message")
def test_verbose_with_error_trace(self): with CrateShell(error_trace=True) as cmd: cmd.logger = Mock() cmd.cursor.execute = Mock(side_effect=ProgrammingError( msg="the error message", error_trace="error trace")) cmd.execute("select invalid statement") cmd.logger.critical.assert_any_call("the error message") cmd.logger.critical.assert_called_with("\nerror trace")
def run_selects(c, version): for stmt in SELECT_STATEMENTS: if version in stmt.unsupported_versions: continue try: c.execute(stmt.stmt) except ProgrammingError as e: raise ProgrammingError('Error executing ' + stmt.stmt) from e
def close(self): if self.is_closed(): raise ProgrammingError('CrateShell is already closed') if self.cursor: self.cursor.close() self.cursor = None if self.connection: self.connection.close() self.connection = None
def server_infos(self, server): response = self._request('GET', '', server=server) self._raise_for_status(response) try: content = json.loads(six.text_type(response.data, 'utf-8')) except ValueError: raise ProgrammingError( "Invalid server response of content-type '%s'" % response.headers.get("content-type", "unknown")) node_name = content.get("name") return server, node_name, content.get('version', {}).get('number', '0.0.0')
def _request(self, method, path, server=None, **kwargs): """Execute a request to the cluster A server is selected from the server pool. """ while True: next_server = server or self._get_server() try: response = self.server_pool[next_server].request( method, path, username=self.username, password=self.password, backoff_factor=self.backoff_factor, schema=self.schema, **kwargs) redirect_location = response.get_redirect_location() if redirect_location and 300 <= response.status <= 308: redirect_server = _server_url(redirect_location) self._add_server(redirect_server) return self._request(method, path, server=redirect_server, **kwargs) if not server and response.status in SRV_UNAVAILABLE_STATUSES: with self._lock: # drop server from active ones self._drop_server(next_server, response.reason) else: return response except ( MaxRetryError, ReadTimeoutError, SSLError, HTTPError, ProxyError, ) as ex: ex_message = _ex_to_message(ex) if server: raise ConnectionError( "Server not available, exception: %s" % ex_message) preserve_server = False if isinstance(ex, ProtocolError): preserve_server = any( t in [type(arg) for arg in ex.args] for t in PRESERVE_ACTIVE_SERVER_EXCEPTIONS) if (not preserve_server): with self._lock: # drop server from active ones self._drop_server(next_server, ex_message) except Exception as e: raise ProgrammingError(_ex_to_message(e))
def _request(self, method, path, server=None, **kwargs): """Execute a request to the cluster A server is selected from the server pool. """ while True: next_server = server or self._get_server() try: response = self.server_pool[next_server].request( method, path, username=self.username, password=self.password, schema=self.schema, **kwargs) redirect_location = response.get_redirect_location() if redirect_location and 300 <= response.status <= 308: redirect_server = _server_url(redirect_location) self._add_server(redirect_server) return self._request(method, path, server=redirect_server, **kwargs) if not server and response.status in SRV_UNAVAILABLE_STATUSES: with self._lock: # drop server from active ones self._drop_server(next_server, response.reason) else: return response except ( urllib3.exceptions.MaxRetryError, urllib3.exceptions.ReadTimeoutError, urllib3.exceptions.SSLError, urllib3.exceptions.HTTPError, urllib3.exceptions.ProxyError, ) as ex: ex_message = _ex_to_message(ex) if server: raise ConnectionError( "Server not available, exception: %s" % ex_message) with self._lock: # drop server from active ones self._drop_server(next_server, ex_message) except Exception as e: raise ProgrammingError(_ex_to_message(e))
def _json_request(self, method, path, data=None): """ Issue request against the crate HTTP API. """ if data: data = json.dumps(data) response = self._request(method, path, data=data) # raise error if occurred, otherwise nothing is raised self._raise_for_status(response) # return parsed json response if len(response.data) > 0: try: return json.loads(six.text_type(response.data, 'utf-8')) except ValueError: raise ProgrammingError( "Invalid server response of content-type '%s'" % response.headers.get("content-type", "")) return response.data
def mock_execute(self, cmd): if 'current_user' in cmd: raise ProgrammingError() return self.execute(cmd)