Skip to content

fix: UK VAT service 404 (not found) misreported as service outage#15

Draft
akinsteph wants to merge 1 commit into
masterfrom
fix/14-hmrc-404-not-outage
Draft

fix: UK VAT service 404 (not found) misreported as service outage#15
akinsteph wants to merge 1 commit into
masterfrom
fix/14-hmrc-404-not-outage

Conversation

@akinsteph

Copy link
Copy Markdown

AI-generated PR. This pull request was implemented by an AI agent (Claude Sonnet 4.6) following a groomed plan for issue #14. Please review carefully before merging.

Summary

Fixes #14.

HMRCRegistry.check_vat_number treated an HTTP 404 from the HMRC VAT-check API exactly like a generic outage (timeout, 500, malformed response, wrong content type) — logging a "Response is nondeterministic..." line and returning is_valid=False with no way for a caller to distinguish "VAT number not found" from "the service is down."

A 404 from this API is a deterministic answer, not an outage: the VAT number does not exist in HMRC's registry. This PR adds a dedicated branch that catches status_code == 404 before the existing generic status/content-type check, logs a plain "VAT number not found (404 NOT_FOUND)" line instead, and returns is_valid=False with no outage/nondeterministic signal.

All other error paths (timeouts, 500s, non-JSON content type, other non-200 statuses) are untouched, so downstream outage detection (e.g. wp-media/monies, which greps log_lines for "Response is nondeterministic") keeps working exactly as before.

Changes

  • pyvat/registries.py: added a response.status_code == 404 branch in HMRCRegistry.check_vat_number, placed immediately before the existing if response.status_code != 200 or ... outage check. No signature or public API changes.
  • tests/test_hmrc_registry.py (new): regression tests for the HMRC registry using unittest.mock.patch on requests.get (no live HMRC calls), covering:
    • 404 → is_valid=False, no nondeterministic/exception/ServerError signal in log_lines
    • 500 → is_valid=False, nondeterministic present in log_lines (outage path still works)
    • 200 with a valid target payload → is_valid=True, business_name/business_address populated
    • 200 with a non-JSON content type → still flagged nondeterministic
    • Timeout → still flagged as a timed-out request

Acceptance criteria

  • A 404 response results in is_valid=False without any exception, ServerError, or nondeterministic/service-unavailable signal in result.log_lines.
  • A genuine outage (timeout, 500, malformed/non-JSON response, non-404 non-200 status) still results in a nondeterministic log line.
  • Regression tests cover 404, 500, and 200 cases.

Test plan

  • python -m pytest tests/ -v — 21 passed, 2 skipped (pre-existing, network-dependent live-VAT-check tests unrelated to this change).
  • Manual smoke test through the public pyvat.check_vat_number() entry point with a mocked 404 response, confirming is_valid=False and no outage signal in log_lines.
  • flake8 run on the changed file — no new violations introduced (pre-existing violations on unrelated lines untouched).

Notes

  • No public API surface changed (no new endpoints, config keys, or signature changes), so no documentation updates were needed.
  • This repo had no existing mocking convention for HTTP calls in tests; unittest.mock.patch on requests.get was used for the new test file, seeding access_token on the registry instance in setUp so the _authenticate() retry path (which itself makes an HTTP call) doesn't need to be mocked for these tests.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

HMRCRegistry.check_vat_number returned the generic "nondeterministic"
outage signal for a 404 response, even though a 404 is a deterministic
"VAT number not found" result from the HMRC API. Add a dedicated 404
branch before the existing status/content-type check so 404s are
reported as invalid without the outage signal, while timeouts, 500s,
and malformed responses still trigger the outage path unchanged.

Fixes #14

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nicomollet

Copy link
Copy Markdown

@akinsteph Looks good we would be more confortable with a test on Monies staging.

Create an issue for Monies (update Pyvat) and PR pointing to this Pyvat commit and test with a UK/GB VAT number:


Monies staging to test

curl --location 'https://monies-staging.wp-media.me/api/vat/vat-rate/?country_code=GB&vat_number=GB674107243' \
--header 'Content: application/json' \
--header 'Authorization: token 27129e1267ef2e0f2b12ecbd14e64eb1854ad446' \
--header 'Accept: application/json' \
--data ''

Current behavior on Monies production:

curl --location 'https://monies.wp-media.me/api/vat/vat-rate/?country_code=GB&vat_number=GB674107243' \
--header 'Content: application/json' \
--header 'Authorization: token xxx' \
--header 'Accept: application/json' \
--data ''

{
    "country_vat_rate": 20.0,
    "regional_vat_rate": 20.0,
    "user_vat_rate": 20.0,
    "validation_error": "VAT validation remote service is not available"
}

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.

UK VAT service — 404 (VAT number not found) is misreported as a service outage

2 participants