Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Pydantic error mapping #4170

Merged
merged 7 commits into from
Jan 30, 2025
Merged
Changes from all commits
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
37 changes: 25 additions & 12 deletions cg/services/orders/validation/model_validator/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,15 @@ def create_case_sample_error(error: ErrorDetails) -> CaseSampleError:
What follows below are ways of extracting data from a Pydantic ErrorDetails object. The aim is to find out
where the error occurred, for which the 'loc' value (which is a tuple) can be used. It is generally structured in
alternating strings and ints, specifying field names and list indices. An example:
if loc = ('cases', 3, 'samples', 2, 'well_position'), that means that the error stems from the well_position of the
third sample in the fourth case.
if loc = ('samples', 2, 'well_position'), that means that the error stems from the well_position of the
third sample in the order.

As an additional point of complexity, the discriminator is also added to the loc, specifically in
OrdersWithCases which have a discriminator for both cases and samples specifying if it is a new
or existing case/sample. So
loc = ('cases', 0, 'new', 'priority')
means that the error concerns the first case in the order, which is a new case, and it concerns the field
'priority'.
"""


Expand All @@ -122,48 +129,54 @@ def get_order_error_details(error_details: list[ErrorDetails]) -> list[ErrorDeta


def is_sample_error(error: ErrorDetails) -> bool:
return len(error["loc"]) == 3 and error["loc"][0] == "samples"
return error["loc"][0] == "samples"


def is_case_error(error: ErrorDetails) -> bool:
return len(error["loc"]) == 4 and error["loc"][0] == "cases"
return "cases" in error["loc"] and "samples" not in error["loc"]


def is_case_sample_error(error: ErrorDetails) -> bool:
return len(error["loc"]) == 7
return "cases" in error["loc"] and "samples" in error["loc"]
islean marked this conversation as resolved.
Show resolved Hide resolved


def is_order_error(error: ErrorDetails) -> bool:
return len(error["loc"]) == 1
return error["loc"][0] not in ["cases", "samples"]
islean marked this conversation as resolved.
Show resolved Hide resolved


def get_error_message(error: ErrorDetails) -> str:
return error["msg"]


def get_sample_field_name(error: ErrorDetails) -> str:
return error["loc"][2]
index_for_field_name: int = error["loc"].index("samples") + 2
return error["loc"][index_for_field_name]


def get_case_field_name(error: ErrorDetails) -> str:
return error["loc"][3]
index_for_field_name: int = error["loc"].index("cases") + 3
diitaz93 marked this conversation as resolved.
Show resolved Hide resolved
return error["loc"][index_for_field_name]


def get_case_sample_field_name(error: ErrorDetails) -> str:
return error["loc"][6]
index_for_field_name: int = error["loc"].index("samples") + 3
islean marked this conversation as resolved.
Show resolved Hide resolved
return error["loc"][index_for_field_name]


def get_order_field_name(error: ErrorDetails) -> str:
return error["loc"][0]


def get_sample_index(error: ErrorDetails) -> int:
return error["loc"][1]
index_for_index: int = error["loc"].index("samples") + 1
islean marked this conversation as resolved.
Show resolved Hide resolved
return error["loc"][index_for_index]


def get_case_index(error: ErrorDetails) -> int:
return error["loc"][1]
index_for_index: int = error["loc"].index("cases") + 1
return error["loc"][index_for_index]


def get_case_sample_index(error: ErrorDetails) -> int:
return error["loc"][4]
index_for_index: int = error["loc"].index("samples") + 1
islean marked this conversation as resolved.
Show resolved Hide resolved
return error["loc"][index_for_index]
Loading