Skip to content

EDM-5201: handle pydantic ValidationError in api_module get()/list() - #66

Merged
EfratIfergan merged 2 commits into
mainfrom
bugfix/EDM-5201-api-module-pydantic-fallback
Aug 26, 2026
Merged

EDM-5201: handle pydantic ValidationError in api_module get()/list()#66
EfratIfergan merged 2 commits into
mainfrom
bugfix/EDM-5201-api-module-pydantic-fallback

Conversation

@EfratIfergan

Copy link
Copy Markdown
Contributor

Problem

The Flight Control client SDK deserializes API responses into pydantic models. When a device has a mount-only application volume (a volume with no image field), the SDK's ApplicationVolume model raises a pydantic ValidationError during deserialization — which is not a subclass of the SDK's ApiException.

FlightctlAPIModule.get() and list() (plugins/module_utils/api_module.py) — the shared chokepoint behind flightctl_resource_info, the device/fleet modules, and approvals — only catch ApiException/NotFoundException. The pydantic error therefore propagated unhandled, crashing the module with a raw Python traceback instead of a clean Ansible failure or a successful read.

EDM-4980 (#63) fixed this same root cause for the inventory plugin only; this change applies the equivalent fix to the shared API module.

Change

  • New plugins/module_utils/sdk_utils.py — extracts the pydantic-detection helper into a shared location as is_pydantic_validation_error(), plus a small raw_response_to_dict() helper. The inventory plugin now imports the shared helper (keeping its _is_pydantic_validation_error name as an alias), removing the duplicate definition.
  • plugins/module_utils/api_module.pyget() and list() now catch a pydantic ValidationError, warn, and retry against the SDK's *_without_preload_content raw endpoints, returning lightweight RawResource/RawListResponse wrappers that expose the same to_dict() / items/metadata/summary interface downstream consumers (get_one_or_many(), ListResult.to_dict()) already expect. Non-pydantic exceptions are re-raised unchanged; a failure of the raw retry surfaces a clean FlightctlApiException.

Tests

  • tests/unit/plugins/module_utils/test_sdk_utils.py (new) — unit tests for the shared helpers.
  • tests/unit/plugins/module_utils/test_api_module.py — fallback tests covering the exact ticket scenario (device get with a mount-only volume), the rendered-device path, list() with items/metadata/summary, end-to-end get_one_or_many() serialization, non-pydantic re-raise, and raw-retry failure → FlightctlApiException.

Full unit suite: 230 passed (inventory suite unaffected: 80 passed).

Reproduction / Verification

  1. Create a device with an application that has a mount-only volume (no image).
  2. Run flightctl_resource_info: kind=Device against it.
  3. Before: raw pydantic traceback. After: the read succeeds via the raw-JSON fallback (with a warning), or fails cleanly as a FlightctlApiException.

🤖 Generated with Claude Code

The Flight Control client SDK deserializes API responses into pydantic
models. A device with a mount-only application volume (no `image`) makes
the SDK's ApplicationVolume model raise a pydantic ValidationError, which
is not a subclass of ApiException. FlightctlAPIModule.get()/list() — the
shared chokepoint behind flightctl_resource_info, device/fleet modules,
and approvals — only caught ApiException, so the error propagated as an
unhandled traceback.

Apply the same raw-JSON fallback already used by the inventory plugin
(EDM-4980): on a pydantic ValidationError, retry against the SDK's
*_without_preload_content endpoints and wrap the payload so downstream
consumers keep working. Extract the pydantic-detection helper into a
shared module_utils/sdk_utils.py used by both the inventory plugin and
api_module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: be6fecd0-5860-4a95-bd3c-2c9a9b40489d


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Add an end-to-end test that provokes a genuine pydantic ValidationError
from the SDK's ApplicationVolume model (mount-only volume without `image`)
and asserts FlightctlAPIModule.get() recovers via the raw-JSON fallback.
This proves the ticket premise against the real SDK rather than a
stand-in error. The test skips if the SDK model shape changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@EfratIfergan
EfratIfergan marked this pull request as ready for review August 23, 2026 08:17
@EfratIfergan
EfratIfergan merged commit 0244b98 into main Aug 26, 2026
8 checks passed
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.

2 participants