Skip to content

Reject invalid $evaluate measure inputs with typed exceptions#1025

Draft
lukedegruchy wants to merge 1 commit into
mainfrom
ld-20260504-evaluate-basic-error-handling
Draft

Reject invalid $evaluate measure inputs with typed exceptions#1025
lukedegruchy wants to merge 1 commit into
mainfrom
ld-20260504-evaluate-basic-error-handling

Conversation

@lukedegruchy
Copy link
Copy Markdown
Contributor

Two early-validation failures previously surfaced as confusing errors: a non-existent measureUrl produced a NullPointerException, and an empty measure-reference list silently flowed through and failed downstream with "Expected only a single MeasureReport but got multiples".

Introduce InvalidMeasureRequestException as a shared parent for client- input errors in cqf-fhir-cr, with InvalidMeasureDefinitionException (re-parented) and a new MeasureLookupException as children. The HAPI provider catches the parent type at the boundary and translates to InvalidRequestException (HTTP 400), which also upgrades the existing empty-stratifier case from PR #1019 from 500 to 400.

  • R4MeasureServiceUtils.resolveByUrl: throw MeasureLookupException for zero or multiple matches (mirroring resolveByIdentifier).
  • R4MultiMeasureService.evaluateToListOfList: reject empty measureRefs upfront, covering both the production evaluate path and the test-only evaluateWithDefs path.
  • MeasureOperationsProvider (R4): wrap evaluateMeasure and evaluate in a single try/catch translating InvalidMeasureRequestException to InvalidRequestException.

Two early-validation failures previously surfaced as confusing errors:
a non-existent measureUrl produced a NullPointerException, and an empty
measure-reference list silently flowed through and failed downstream
with "Expected only a single MeasureReport but got multiples".

Introduce InvalidMeasureRequestException as a shared parent for client-
input errors in cqf-fhir-cr, with InvalidMeasureDefinitionException
(re-parented) and a new MeasureLookupException as children. The HAPI
provider catches the parent type at the boundary and translates to
InvalidRequestException (HTTP 400), which also upgrades the existing
empty-stratifier case from PR #1019 from 500 to 400.

- R4MeasureServiceUtils.resolveByUrl: throw MeasureLookupException for
  zero or multiple matches (mirroring resolveByIdentifier).
- R4MultiMeasureService.evaluateToListOfList: reject empty measureRefs
  upfront, covering both the production evaluate path and the test-only
  evaluateWithDefs path.
- MeasureOperationsProvider (R4): wrap evaluateMeasure and evaluate in
  a single try/catch translating InvalidMeasureRequestException to
  InvalidRequestException.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Formatting check succeeded!

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
70.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant