Skip to content

Commit 5343c59

Browse files
SK-1889: Merge branch 'v2' into SK-1889-partial-error-cases-when-continue-on-error
2 parents 0218059 + b98aab0 commit 5343c59

File tree

6 files changed

+54
-23
lines changed

6 files changed

+54
-23
lines changed

skyflow/utils/_skyflow_messages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class ErrorLogs(Enum):
277277
UPDATE_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Update request resulted in failure."
278278
QUERY_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Query request resulted in failure."
279279
GET_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Get request resulted in failure."
280+
INVOKE_CONNECTION_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Invoke connection request resulted in failure."
280281

281282
class Interface(Enum):
282283
INSERT = "INSERT"

skyflow/utils/_utils.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -330,24 +330,30 @@ def parse_invoke_connection_response(api_response: requests.Response):
330330

331331
invoke_connection_response.response = json_content
332332
return invoke_connection_response
333-
except:
333+
except Exception as e:
334334
raise SkyflowError(SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format(content), status_code)
335335
except HTTPError:
336-
message = SkyflowMessages.Error.API_ERROR.value.format(status_code)
337-
if api_response and api_response.content:
338-
try:
339-
error_response = json.loads(content)
340-
if isinstance(error_response.get('error'), dict) and 'message' in error_response['error']:
341-
message = error_response['error']['message']
342-
except json.JSONDecodeError:
343-
message = SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format(content)
344-
345-
if 'x-request-id' in api_response.headers:
346-
message += ' - request id: ' + api_response.headers['x-request-id']
347-
336+
message = SkyflowMessages.Error.API_ERROR.value.format(status_code)
337+
try:
338+
error_response = json.loads(content)
339+
request_id = api_response.headers['x-request-id']
340+
error_from_client = api_response.headers.get('error-from-client')
341+
342+
status_code = error_response.get('error', {}).get('http_code', 500) # Default to 500 if not found
343+
http_status = error_response.get('error', {}).get('http_status')
344+
grpc_code = error_response.get('error', {}).get('grpc_code')
345+
details = error_response.get('error', {}).get('details')
346+
message = error_response.get('error', {}).get('message', "An unknown error occurred.")
347+
348+
if error_from_client is not None:
349+
if details is None: details = []
350+
details.append({'error_from_client': error_from_client})
351+
352+
raise SkyflowError(message, status_code, request_id, grpc_code, http_status, details)
353+
except json.JSONDecodeError:
354+
message = SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format(content)
348355
raise SkyflowError(message, status_code)
349356

350-
351357
def log_and_reject_error(description, status_code, request_id, http_status=None, grpc_code=None, details=None, logger = None):
352358
raise SkyflowError(description, status_code, request_id, grpc_code, http_status, details)
353359

skyflow/utils/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
SDK_VERSION = '2.0.0b1.dev0+dcb5ddc'
1+
SDK_VERSION = '2.0.0b1.dev0+dcb5ddc'

skyflow/vault/controller/_connections.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from skyflow.error import SkyflowError
44
from skyflow.utils import construct_invoke_connection_request, SkyflowMessages, get_metrics, \
55
parse_invoke_connection_response
6-
from skyflow.utils.logger import log_info
6+
from skyflow.utils.logger import log_info, log_error_log
77
from skyflow.vault.connection import InvokeConnectionRequest
88

99

@@ -27,7 +27,7 @@ def invoke(self, request: InvokeConnectionRequest):
2727

2828
invoke_connection_request.headers['sky-metadata'] = json.dumps(get_metrics())
2929

30-
log_info(SkyflowMessages.Info.INVOKE_CONNECTION_TRIGGERED, self.__vault_client.get_logger())
30+
log_info(SkyflowMessages.Info.INVOKE_CONNECTION_TRIGGERED.value, self.__vault_client.get_logger())
3131

3232
try:
3333
response = session.send(invoke_connection_request)
@@ -36,5 +36,7 @@ def invoke(self, request: InvokeConnectionRequest):
3636
return invoke_connection_response
3737

3838
except Exception as e:
39+
log_error_log(SkyflowMessages.ErrorLogs.INVOKE_CONNECTION_REQUEST_REJECTED.value, self.__vault_client.get_logger())
40+
if isinstance(e, SkyflowError): raise e
3941
raise SkyflowError(SkyflowMessages.Error.INVOKE_CONNECTION_FAILED.value,
4042
SkyflowMessages.ErrorCodes.SERVER_ERROR.value)

tests/utils/test__utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ def test_parse_invoke_connection_response_http_error_with_json_error_message(sel
356356
with self.assertRaises(SkyflowError) as context:
357357
parse_invoke_connection_response(mock_response)
358358

359-
self.assertEqual(context.exception.message, "Not Found - request id: 1234")
359+
self.assertEqual(context.exception.message, "Not Found")
360+
self.assertEqual(context.exception.request_id, "1234")
360361

361362
@patch("requests.Response")
362363
def test_parse_invoke_connection_response_http_error_without_json_error_message(self, mock_response):
@@ -369,7 +370,7 @@ def test_parse_invoke_connection_response_http_error_without_json_error_message(
369370
with self.assertRaises(SkyflowError) as context:
370371
parse_invoke_connection_response(mock_response)
371372

372-
self.assertEqual(context.exception.message, SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format("Internal Server Error") + " - request id: 1234")
373+
self.assertEqual(context.exception.message, SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format("Internal Server Error"))
373374

374375
@patch("skyflow.utils._utils.log_and_reject_error")
375376
def test_handle_exception_json_error(self, mock_log_and_reject_error):

tests/vault/controller/test__connection.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import unittest
22
from unittest.mock import Mock, patch
3-
3+
import requests
44
from skyflow.error import SkyflowError
5-
from skyflow.utils import SkyflowMessages
5+
from skyflow.utils import SkyflowMessages, parse_invoke_connection_response
66
from skyflow.utils.enums import RequestMethod
7+
from skyflow.utils._version import SDK_VERSION
78
from skyflow.vault.connection import InvokeConnectionRequest
89
from skyflow.vault.controller import Connection
910

@@ -21,7 +22,8 @@
2122
INVALID_HEADERS = "invalid_headers"
2223
INVALID_BODY = "invalid_body"
2324
FAILURE_STATUS_CODE = 400
24-
ERROR_RESPONSE_CONTENT = '{"error": {"message": "error occurred"}}'
25+
ERROR_RESPONSE_CONTENT = '"message": "Invalid Request"'
26+
ERROR_FROM_CLIENT_RESPONSE_CONTENT = b'{"error": {"message": "Invalid Request"}}'
2527

2628
class TestConnection(unittest.TestCase):
2729
def setUp(self):
@@ -99,6 +101,25 @@ def test_invoke_request_error(self, mock_send):
99101

100102
with self.assertRaises(SkyflowError) as context:
101103
self.connection.invoke(request)
102-
self.assertEqual(context.exception.message, SkyflowMessages.Error.INVOKE_CONNECTION_FAILED.value)
104+
self.assertEqual(context.exception.message, f'Skyflow Python SDK {SDK_VERSION} Response {ERROR_RESPONSE_CONTENT} is not valid JSON.')
105+
self.assertEqual(context.exception.message, SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format(ERROR_RESPONSE_CONTENT))
106+
self.assertEqual(context.exception.http_code, 400)
107+
108+
def test_parse_invoke_connection_response_error_from_client(self):
109+
mock_response = Mock(spec=requests.Response)
110+
mock_response.status_code = FAILURE_STATUS_CODE
111+
mock_response.content = ERROR_FROM_CLIENT_RESPONSE_CONTENT
112+
mock_response.headers = {
113+
'error-from-client': 'true',
114+
'x-request-id': '12345'
115+
}
116+
mock_response.raise_for_status.side_effect = requests.HTTPError()
117+
118+
with self.assertRaises(SkyflowError) as context:
119+
parse_invoke_connection_response(mock_response)
120+
121+
exception = context.exception
103122

123+
self.assertTrue(any(detail.get('error_from_client') == 'true' for detail in exception.details))
124+
self.assertEqual(exception.request_id, '12345')
104125

0 commit comments

Comments
 (0)