Skip to content

POST /api/v1/hgvs/validate returns 500 for malformed input #860

Description

@bencap

Summary

Malformed input to the HGVS validation endpoint returns HTTP 500 and fires a Slack error alert, when it should return a 4XX client error.

Problem

In hgvs_validate (in the hgvs router), the parser call hp.parse(variant["variant"]) runs outside the try/except. A syntactically invalid variant string raises HGVSParseError at the parse stage so it propagates to CatchAllErrorMiddleware and becomes a 500. Only HGVSInvalidVariantError, raised later at the validate stage, is caught today.

The free-form variant: dict[str, str] request body has the same failure mode: a request missing the variant key raises KeyError, also surfacing as a 500.

Both failures stem from caller-supplied input and should be 4XX.

Steps to reproduce

  1. POST /api/v1/hgvs/validate with body {"variant": "NM_001256054.2:c.-45+163GGGGCC[(145_?)]"} (or any unparseable HGVS string).
  2. POST /api/v1/hgvs/validate with body {}.

Expected: 400 for the unparseable string; 422 for the missing field.

Observed: 500 for both, each accompanied by a Slack error alert. The unparseable-string case logs HGVSParseError originating from the parse call in the hgvs router.

Proposed behavior

  • Move hp.parse() inside the error handler and catch the base class hgvs.exceptions.HGVSError, so any HGVS-level failure — unparseable string, inconsistent variant, unknown accession — returns 400. This matches the existing precedent that catches HGVSError in the dataframe variant validation library.
  • Replace the dict[str, str] body with a typed request view model exposing a required variant: str field. FastAPI then returns 422 for a missing or mistyped field automatically, and the request schema is self-documenting in OpenAPI. The field name stays variant, so there is no client contract change.
  • Update the endpoint's documented responses from the 400-only set to the combined validation set (400 + 422).

Acceptance criteria

  • An unparseable HGVS string returns 400, not 500.
  • A request body missing the variant field returns 422, not 500.
  • A valid-but-inconsistent variant still returns 400 (unchanged).
  • Neither input case triggers the 500-path Slack alert.
  • Router tests cover the unparseable-string (400) and missing-field (422) cases.

Implementation notes

  • Add the request model as a new hgvs view model (variant: str) extending the shared base model; its camelize alias generator leaves the single-word field as variant.
  • After the API change, regenerate the UI's OpenAPI schema types so they reflect the typed request body.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app: backendTask implementation touches the backend

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions