Skip to content

Commit a868875

Browse files
jopemachineclaude
andcommitted
refactor(BA-6003): use BackendAIModelValidationFailed.errors() accessor
Switch every caller that iterates ``BackendAIModelValidationFailed``'s per-field error list from the verbose ``(e.extra_data or {}).get("errors", [])`` to the new ``e.errors()`` classmethod (mirrors ``pydantic.ValidationError.errors()``): * 7 ``_build_dto`` CLI helpers in ``client/cli/v2/admin/*`` and ``client/cli/v2/model_card/commands.py``. * The ``pydantic_params_api_handler`` decorator in ``manager/api/utils.py``. Also drop a duplicate ``ModelDefinitionValidationError`` class that slipped back in during a rebase. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 352fbf2 commit a868875

9 files changed

Lines changed: 8 additions & 27 deletions

File tree

src/ai/backend/client/cli/v2/admin/deployment_revision_preset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2525
return dto_cls.model_validate(data)
2626
except BackendAIModelValidationFailed as e:
2727
click.echo("Validation error:", err=True)
28-
for err in (e.extra_data or {}).get("errors", []):
28+
for err in e.errors():
2929
field = ".".join(str(loc) for loc in err["loc"])
3030
click.echo(f" {field}: {err['msg']}", err=True)
3131
sys.exit(1)

src/ai/backend/client/cli/v2/admin/model_card.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2525
return dto_cls.model_validate(data)
2626
except BackendAIModelValidationFailed as e:
2727
click.echo("Validation error:", err=True)
28-
for err in (e.extra_data or {}).get("errors", []):
28+
for err in e.errors():
2929
field = ".".join(str(loc) for loc in err["loc"])
3030
click.echo(f" {field}: {err['msg']}", err=True)
3131
sys.exit(1)

src/ai/backend/client/cli/v2/admin/resource_policy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
5454
return dto_cls.model_validate(data)
5555
except BackendAIModelValidationFailed as e:
5656
click.echo("Validation error:", err=True)
57-
for err in (e.extra_data or {}).get("errors", []):
57+
for err in e.errors():
5858
field = ".".join(str(loc) for loc in err["loc"])
5959
click.echo(f" {field}: {err['msg']}", err=True)
6060
sys.exit(1)

src/ai/backend/client/cli/v2/admin/resource_preset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2626
return dto_cls.model_validate(data)
2727
except BackendAIModelValidationFailed as e:
2828
click.echo("Validation error:", err=True)
29-
for err in (e.extra_data or {}).get("errors", []):
29+
for err in e.errors():
3030
field = ".".join(str(loc) for loc in err["loc"])
3131
click.echo(f" {field}: {err['msg']}", err=True)
3232
sys.exit(1)

src/ai/backend/client/cli/v2/admin/runtime_variant.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2525
return dto_cls.model_validate(data)
2626
except BackendAIModelValidationFailed as e:
2727
click.echo("Validation error:", err=True)
28-
for err in (e.extra_data or {}).get("errors", []):
28+
for err in e.errors():
2929
field = ".".join(str(loc) for loc in err["loc"])
3030
click.echo(f" {field}: {err['msg']}", err=True)
3131
sys.exit(1)

src/ai/backend/client/cli/v2/admin/runtime_variant_preset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2525
return dto_cls.model_validate(data)
2626
except BackendAIModelValidationFailed as e:
2727
click.echo("Validation error:", err=True)
28-
for err in (e.extra_data or {}).get("errors", []):
28+
for err in e.errors():
2929
field = ".".join(str(loc) for loc in err["loc"])
3030
click.echo(f" {field}: {err['msg']}", err=True)
3131
sys.exit(1)

src/ai/backend/client/cli/v2/model_card/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def _build_dto(dto_cls: type, data: dict[str, Any]) -> Any:
2525
return dto_cls.model_validate(data)
2626
except BackendAIModelValidationFailed as e:
2727
click.echo("Validation error:", err=True)
28-
for err in (e.extra_data or {}).get("errors", []):
28+
for err in e.errors():
2929
field = ".".join(str(loc) for loc in err["loc"])
3030
click.echo(f" {field}: {err['msg']}", err=True)
3131
sys.exit(1)

src/ai/backend/common/exception.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -493,24 +493,6 @@ def error_code(self) -> ErrorCode:
493493
)
494494

495495

496-
class ModelDefinitionValidationError(BackendAIError, web.HTTPBadRequest):
497-
"""Raised by :class:`ai.backend.common.config.ModelDefinition` when
498-
its ``model_validate`` call fails. Lives in ``common`` so the model
499-
itself (also in ``common``) can construct it via
500-
:meth:`BackendAIModel.build_validation_error`, with no caller-side
501-
re-wrap needed."""
502-
503-
error_type = "https://api.backend.ai/probs/model-definition-validation-failed"
504-
error_title = "Model definition validation failed."
505-
506-
def error_code(self) -> ErrorCode:
507-
return ErrorCode(
508-
domain=ErrorDomain.MODEL_SERVICE,
509-
operation=ErrorOperation.ACCESS,
510-
error_detail=ErrorDetail.INVALID_PARAMETERS,
511-
)
512-
513-
514496
class DeprecatedAPI(BackendAIError, web.HTTPBadRequest):
515497
error_type = "https://api.backend.ai/probs/deprecated"
516498
error_title = "This API is deprecated."

src/ai/backend/manager/api/utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ async def wrapped(
224224
except (json.decoder.JSONDecodeError, yaml.YAMLError, yaml.MarkedYAMLError) as e:
225225
raise InvalidAPIParameters("Malformed body") from e
226226
except BackendAIModelValidationFailed as ex:
227-
errors = (ex.extra_data or {}).get("errors") or []
228-
first_error = errors[0]
227+
first_error = ex.errors()[0]
229228
# Format the first validation error as the message
230229
# The client may refer extra_data to access the full validation errors.
231230
metadata = {

0 commit comments

Comments
 (0)