From d6f7008fb8ea774528b417094adf5238d5a80593 Mon Sep 17 00:00:00 2001 From: Irfan Baig Date: Wed, 20 May 2026 16:48:55 -0500 Subject: [PATCH 1/2] feat: Error Handler for connect, studies, datasets and dataset_versions --- dataconnect/service/default.py | 6 +----- .../transport/arrow_flight/error_handler.py | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dataconnect/service/default.py b/dataconnect/service/default.py index 4f81317..68777c3 100644 --- a/dataconnect/service/default.py +++ b/dataconnect/service/default.py @@ -66,9 +66,8 @@ def get_dataset_versions(self, dataset_uuid: UUID) -> list[DatasetVersion]: A list of :class:`DatasetVersion` objects for the given dataset. Raises: - ValidationError: If *dataset_uuid* is not a valid, non-zero UUID. + ValidationError: If *dataset_uuid* is not a valid UUID (upstream). """ - validate_uuid(dataset_uuid, field_name="dataset_uuid", error_code="VAL_C_DATASET_UUID") request = ResourceQuery(action=_ACTION_LIST_DATASET_VERSIONS).append_body({"dataset_uuid": str(dataset_uuid)}) @@ -147,9 +146,6 @@ def get_datasets( Returns: A :class:`PaginatedResponse` of :class:`Dataset` items matching the criteria. """ - validate_uuid(study_environment_uuid, field_name="study_environment_uuid", error_code="VAL_C_STUDY_ENV_UUID") - validate_positive_int(page, field_name="page", error_code="VAL_C_PAGE") - validate_positive_int(page_size, field_name="page_size", error_code="VAL_C_PAGE_SIZE") request = ResourceQuery(action=_ACTION_LIST_DATASETS).append_body( { diff --git a/dataconnect/transport/arrow_flight/error_handler.py b/dataconnect/transport/arrow_flight/error_handler.py index 974cbf1..a8bd78e 100644 --- a/dataconnect/transport/arrow_flight/error_handler.py +++ b/dataconnect/transport/arrow_flight/error_handler.py @@ -72,10 +72,15 @@ def _extract_json_object(text: str) -> str: "Data Connect > Developer Center." ) +_AUTH_HOST_MSG = ( + "Verify that the host URL is correct and that your network " + "allows outbound connections to the specified host and port." +) + _RATE_LIMIT_DETAIL_MSG = "Wait before making more requests." _ENODIA_PATTERN = re.compile( - r"FlightUnauthenticatedError|Flight returned unauthenticated error", + r"FlightUnauthenticatedError|Flight returned unauthenticated error|Flight returned unavailable error", re.IGNORECASE, ) @@ -108,6 +113,8 @@ def _normalize_enodia_error(error_message: str) -> str: server_msg = raw.strip() if server_msg: + payload_field = "token" + if re.search("authorization header not present", server_msg, re.IGNORECASE): error_code = "AUTH_E_001" clean_msg = "Authentication token is missing from the request." @@ -124,6 +131,11 @@ def _normalize_enodia_error(error_message: str) -> str: error_code = "AUTH_E_004" clean_msg = "Rate limit exceeded." detail_expected = _RATE_LIMIT_DETAIL_MSG + elif re.search("errors resolving", server_msg, re.IGNORECASE): + error_code = "AUTH_E_005" + clean_msg = "Hostname lookup failed." + detail_expected = _AUTH_HOST_MSG + payload_field = "host" else: error_code = "AUTH_E_001" clean_msg = "Authentication token is missing from the request." @@ -139,7 +151,7 @@ def _normalize_enodia_error(error_message: str) -> str: "error_code": error_code, "message": clean_msg, "timestamp": timestamp, - "details": [{"field": "token", "message": None, "expected": detail_expected}], + "details": [{"field": payload_field, "message": None, "expected": detail_expected}], } json_payload = json.dumps(payload) From 211f8667e19c9d5881959d87d5b00f97d2725d04 Mon Sep 17 00:00:00 2001 From: Irfan Baig Date: Wed, 20 May 2026 17:05:02 -0500 Subject: [PATCH 2/2] feat: copilot feedback --- dataconnect/transport/arrow_flight/error_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dataconnect/transport/arrow_flight/error_handler.py b/dataconnect/transport/arrow_flight/error_handler.py index a8bd78e..328fe40 100644 --- a/dataconnect/transport/arrow_flight/error_handler.py +++ b/dataconnect/transport/arrow_flight/error_handler.py @@ -112,9 +112,9 @@ def _normalize_enodia_error(error_message: str) -> str: raw = re.sub(r"\. Client context:.*$", "", raw) server_msg = raw.strip() - if server_msg: - payload_field = "token" + payload_field = "token" + if server_msg: if re.search("authorization header not present", server_msg, re.IGNORECASE): error_code = "AUTH_E_001" clean_msg = "Authentication token is missing from the request."