Skip to content

Convert Pydantic ValidationError to per-domain error classes (return 400 instead of 500) #11513

@jopemachine

Description

@jopemachine

Objective

Catch pydantic.ValidationError raised at service / business-logic call sites and translate it into per-domain BackendAIError subclasses so that bad user payloads return HTTP 400 with human-readable, structured field-level error messages instead of bubbling up as HTTP 500.

Background

Several model_validate() calls in service / GraphQL / handler logic let ValidationError propagate up unhandled. The user receives a generic 500 with a noisy repr of the exception. The goal is to give each call site its own domain error class so the response code, error_code, and message clearly tell the client what went wrong.

Scope

  • New domain error classes: InvalidSessionCreationConfig (errors/kernel.py), InvalidResourceOpts (errors/kernel.py), InvalidScalingGroupOpts (errors/resource.py), InvalidManagerConfig (errors/resource.py).
  • Shared helper format_pydantic_validation_errors() in common/exception.py producing both a human-readable summary ("body.user.email: invalid email; body.age: must be >= 0") and a structured errors list.
  • Wrap call sites: api/rest/session/handler.py V1-V7 CreationConfig (12 sites), services/session/service.py:1574, services/model_serving/services/model_serving.py:622, registry.py:1020, services/model_card/service.py:186, gql_legacy/scaling_group.py:683 and :728, gql_legacy/service_config.py:200.
  • Improve common parsing layer message format: common/api_handlers.py decorators preserve location prefix (body / query / header / path); manager/api/utils.py pydantic_params_api_handler keeps all field errors instead of just the first.
  • Out of scope: external system response parsing (storage-proxy, agent, appproxy clients), bootstrap config loading, DB row deserialization, internal event serialization.

Acceptance Criteria

  • Bad user payloads at all listed call sites return HTTP 400 (not 500).
  • Each call site raises its own domain-specific error class with a unique error_type and error_code.
  • Response body carries a readable msg summary and a structured data.errors list with loc / msg / type per field.
  • pants check, pants lint, and pants fmt all pass on the touched files.

JIRA Issue: BA-5978

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions