Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added Online Store rest client errors handler
- Small refactor to from_error_detail and FeastErrors
- Fixed tests

Signed-off-by: Theodor Mihalache <tmihalac@redhat.com>
  • Loading branch information
tmihalac committed Sep 5, 2024
commit 17ac1aff66860d55d1c5da0c2ff64b657bf13cbf
41 changes: 18 additions & 23 deletions sdk/python/feast/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def from_error_detail(detail: str) -> Optional["FeastError"]:
module = importlib.import_module(module_name)
class_reference = getattr(module, class_name)

instance = class_reference(message)
instance = class_reference.__new__(class_reference)
setattr(instance, "__overridden_message__", message)
return instance
except Exception as e:
Expand Down Expand Up @@ -133,7 +133,7 @@ def __init__(self, name, project=None):


class RequestDataNotFoundInEntityDfException(FeastObjectNotFoundException):
Comment thread
tmihalac marked this conversation as resolved.
def __init__(self, feature_name, feature_view_name=None):
def __init__(self, feature_name, feature_view_name):
super().__init__(
f"Feature {feature_name} not found in the entity dataframe, but required by feature view {feature_view_name}"
)
Expand Down Expand Up @@ -165,12 +165,12 @@ def __init__(self, bucket):


class SavedDatasetNotFound(FeastObjectNotFoundException):
def __init__(self, name: str, project: str = ""):
def __init__(self, name: str, project: str):
super().__init__(f"Saved dataset {name} does not exist in project {project}")


class ValidationReferenceNotFound(FeastObjectNotFoundException):
def __init__(self, name: str, project: str = ""):
def __init__(self, name: str, project: str):
super().__init__(
f"Validation reference {name} does not exist in project {project}"
)
Expand Down Expand Up @@ -205,21 +205,21 @@ def __init__(self, registry_type: str):


class FeastModuleImportError(FeastError):
def __init__(self, module_name: str, class_name: str = ""):
def __init__(self, module_name: str, class_name: str):
super().__init__(
f"Could not import module '{module_name}' while attempting to load class '{class_name}'"
)


class FeastClassImportError(FeastError):
def __init__(self, module_name: str, class_name: str = ""):
def __init__(self, module_name: str, class_name: str):
super().__init__(
f"Could not import class '{class_name}' from module '{module_name}'"
)


class FeastExtrasDependencyImportError(FeastError):
def __init__(self, extras_type: str, nested_error: str = ""):
def __init__(self, extras_type: str, nested_error: str):
message = (
nested_error
+ "\n"
Expand All @@ -229,16 +229,14 @@ def __init__(self, extras_type: str, nested_error: str = ""):


class FeastOfflineStoreUnsupportedDataSource(FeastError):
def __init__(self, offline_store_name: str, data_source_name: str = ""):
def __init__(self, offline_store_name: str, data_source_name: str):
super().__init__(
f"Offline Store '{offline_store_name}' does not support data source '{data_source_name}'"
)


class FeatureNameCollisionError(FeastError):
def __init__(
self, feature_refs_collisions: List[str], full_feature_names: bool = False
):
def __init__(self, feature_refs_collisions: List[str], full_feature_names: bool):
if full_feature_names:
collisions = [ref.replace(":", "__") for ref in feature_refs_collisions]
error_message = (
Expand All @@ -263,8 +261,8 @@ class SpecifiedFeaturesNotPresentError(FeastError):
def __init__(
self,
specified_features: List[Field],
inferred_features: List[Field] = [],
feature_view_name: str = "",
inferred_features: List[Field],
feature_view_name: str,
):
super().__init__(
f"Explicitly specified features {specified_features} not found in inferred list of features "
Expand Down Expand Up @@ -299,21 +297,21 @@ def __init__(self, auth_config_class_name: str):


class FeastInvalidBaseClass(FeastError):
def __init__(self, class_name: str, class_type: str = ""):
def __init__(self, class_name: str, class_type: str):
super().__init__(
f"Class '{class_name}' should have `{class_type}` as a base class."
)


class FeastOnlineStoreUnsupportedDataSource(FeastError):
def __init__(self, online_store_name: str, data_source_name: str = ""):
def __init__(self, online_store_name: str, data_source_name: str):
super().__init__(
f"Online Store '{online_store_name}' does not support data source '{data_source_name}'"
)


class FeastEntityDFMissingColumnsError(FeastError):
def __init__(self, expected, missing=None):
def __init__(self, expected, missing):
super().__init__(
f"The entity dataframe you have provided must contain columns {expected}, "
f"but {missing} were missing."
Expand All @@ -322,10 +320,7 @@ def __init__(self, expected, missing=None):

class FeastJoinKeysDuringMaterialization(FeastError):
def __init__(
self,
source: str,
join_key_columns: Set[str] = set(),
source_columns: Set[str] = set(),
self, source: str, join_key_columns: Set[str], source_columns: Set[str]
):
super().__init__(
f"The DataFrame from {source} being materialized must have at least {join_key_columns} columns present, "
Expand All @@ -342,7 +337,7 @@ def __init__(self):


class RegistryInferenceFailure(FeastError):
def __init__(self, repo_obj_type: str, specific_issue: str = ""):
def __init__(self, repo_obj_type: str, specific_issue: str):
super().__init__(
f"Inference to fill in missing information for {repo_obj_type} failed. {specific_issue}. "
"Try filling the information explicitly."
Expand Down Expand Up @@ -394,7 +389,7 @@ def __init__(self, expected_column_name: str):


class FeatureViewMissingDuringFeatureServiceInference(FeastError):
def __init__(self, feature_view_name: str, feature_service_name: str = ""):
def __init__(self, feature_view_name: str, feature_service_name: str):
super().__init__(
f"Missing {feature_view_name} feature view during inference for {feature_service_name} feature service."
)
Expand Down Expand Up @@ -473,7 +468,7 @@ def __init__(self, input_dict: dict):


class PermissionNotFoundException(FeastError):
def __init__(self, name, project=None):
def __init__(self, name, project):
super().__init__(f"Permission {name} does not exist in project {project}")


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from fastapi.testclient import TestClient

from feast.errors import PushSourceNotFoundException
from feast.feast_object import FeastObject
from feast.feature_server import get_app
from feast.utils import _utc_now
Expand Down Expand Up @@ -90,21 +91,21 @@ def test_push_source_does_not_exist(python_fs_client):
initial_temp = _get_temperatures_from_feature_server(
python_fs_client, location_ids=[1]
)[0]
response = python_fs_client.post(
"/push",
data=json.dumps(
{
"push_source_name": "push_source_does_not_exist",
"df": {
"location_id": [1],
"temperature": [initial_temp * 100],
"event_timestamp": [str(_utc_now())],
"created": [str(_utc_now())],
},
}
),
)
assert response.status_code == 422
with pytest.raises(PushSourceNotFoundException, match="Unable to find push source 'push_source_does_not_exist'"):
python_fs_client.post(
"/push",
data=json.dumps(
{
"push_source_name": "push_source_does_not_exist",
"df": {
"location_id": [1],
"temperature": [initial_temp * 100],
"event_timestamp": [str(_utc_now())],
"created": [str(_utc_now())],
},
}
),
)


def _get_temperatures_from_feature_server(client, location_ids: List[int]):
Expand Down