Skip to content

Add custom exception hierarchy (#219)#239

Merged
jtdub merged 1 commit intonextfrom
issue-219-exception-hierarchy
Mar 26, 2026
Merged

Add custom exception hierarchy (#219)#239
jtdub merged 1 commit intonextfrom
issue-219-exception-hierarchy

Conversation

@jtdub
Copy link
Contributor

@jtdub jtdub commented Mar 26, 2026

Summary

  • Added HierConfigError as the base exception for all hier_config errors
  • Added DriverNotFoundError (replaces ValueError in get_hconfig_driver/get_hconfig_view)
  • Added InvalidConfigError (replaces ValueError for malformed config/banner parsing)
  • Added IncompatibleDriverError (replaces ValueError in WorkflowRemediation for mismatched drivers)
  • Reparented DuplicateChildError under HierConfigError
  • All new exceptions exported from hier_config.__init__

Test plan

  • New tests/unit/test_exceptions.py with 6 tests covering hierarchy, inheritance, and all raise sites
  • Updated existing tests in test_constructors.py and test_workflows.py to catch specific exception types
  • Full lint + test suite passes (poetry run ./scripts/build.py lint-and-test)

Closes #219

🤖 Generated with Claude Code

Add HierConfigError as the base exception with DriverNotFoundError,
InvalidConfigError, IncompatibleDriverError, and reparent
DuplicateChildError under it. Replace generic ValueError/TypeError
raises in constructors and workflows with specific exception types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jtdub jtdub requested a review from aedwardstx as a code owner March 26, 2026 03:40
@jtdub jtdub requested a review from Copilot March 26, 2026 03:41
@jtdub jtdub merged commit 1568211 into next Mar 26, 2026
7 checks passed
@jtdub jtdub deleted the issue-219-exception-hierarchy branch March 26, 2026 03:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a first-class exception hierarchy for hier_config so callers can catch specific failure modes instead of generic ValueErrors, and updates raise sites/tests accordingly.

Changes:

  • Added HierConfigError base plus DriverNotFoundError, InvalidConfigError, and IncompatibleDriverError; reparented DuplicateChildError.
  • Switched key raise sites in constructors/workflows from ValueError to the new custom exceptions.
  • Updated/added unit tests and exported the new exceptions from hier_config.__init__.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/test_workflows.py Updates expected exception for driver mismatch in WorkflowRemediation.
tests/unit/test_exceptions.py Adds new unit tests covering the exception hierarchy and raise sites.
tests/unit/test_constructors.py Updates constructor-related tests to expect new exception types.
hier_config/workflows.py Raises IncompatibleDriverError for mismatched drivers.
hier_config/exceptions.py Defines the new exception hierarchy and reparents DuplicateChildError.
hier_config/constructors.py Raises DriverNotFoundError / InvalidConfigError at relevant failure points.
hier_config/init.py Re-exports new exceptions at the package top level.
CHANGELOG.md Documents the new exception hierarchy in Unreleased notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 61 to +63
if running_config.driver.__class__ is not generated_config.driver.__class__:
message = "The running and generated configs must use the same driver."
raise ValueError(message)
raise IncompatibleDriverError(message)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WorkflowRemediation docstring still documents Raises: ValueError for driver mismatches, but the implementation now raises IncompatibleDriverError. Please update the docstring to match the new exception type so API docs stay accurate.

Copilot uses AI. Check for mistakes.
Comment on lines 51 to 52
generated_config = get_hconfig(Platform.JUNIPER_JUNOS, "dummy_config")

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s an outdated comment just above this block that says the test ensures a ValueError is raised for mismatched drivers, but the expectation is now IncompatibleDriverError. Please update/remove that comment to keep the test intent accurate.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +20
- Custom exception hierarchy: `HierConfigError` base, `DriverNotFoundError`,
`InvalidConfigError`, `IncompatibleDriverError` (#219). `DuplicateChildError`
reparented under `HierConfigError`.
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changelog entry describes a breaking behavior change (replacing ValueError with custom exceptions and reparenting DuplicateChildError). To match the existing changelog structure (e.g., other breaking renames listed under "Changed"), consider moving this bullet to the "### Changed" section or explicitly calling out that it’s breaking in the "Added" entry.

Copilot uses AI. Check for mistakes.
jtdub added a commit that referenced this pull request Mar 26, 2026
Add HierConfigError as the base exception with DriverNotFoundError,
InvalidConfigError, IncompatibleDriverError, and reparent
DuplicateChildError under it. Replace generic ValueError/TypeError
raises in constructors and workflows with specific exception types.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jtdub added a commit that referenced this pull request Mar 26, 2026
* Add CODEOWNERS file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Literal type constraint for cisco_style_text() style parameter (#189) (#240)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Drop v2 migration utilities, rename to load_driver_rules/load_tag_rules, and reorganize tests (#221)

Remove v2-to-v3 platform mapping functions and constants. Rename
load_hconfig_v2_options to load_driver_rules and load_hconfig_v2_tags
to load_tag_rules, preserving dict-based driver extension for Nautobot
Golden Config compatibility.

Reorganize test suite into unit/, integration/, and benchmarks/
directories mirroring the source code structure. Split the 2079-line
test_hier_config.py into focused files by module (test_root.py,
test_child.py, test_children.py). Separate driver remediation scenario
tests into integration/ and unit tests into unit/platforms/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix load_tag_rules: use _collect_match_rules and correct return type

Replace inline match-rule collection with existing _collect_match_rules
helper for consistency. Simplify return type from
tuple[TagRule] | tuple[TagRule, ...] to tuple[TagRule, ...].

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update gha to test against the next branch

* Fix __hash__/__eq__ inconsistency in HConfigChild (#185) (#236)

* Fix __hash__/__eq__ inconsistency in HConfigChild (#185)

__hash__ included new_in_config and order_weight but __eq__ intentionally
excluded them, violating the Python invariant that a == b implies hash(a) == hash(b).
__eq__ also checked tags but __hash__ did not include them.

Align __hash__ to use the same fields as __eq__: text, tags, and children.

Add five tests covering each dimension of the inconsistency and its practical
impact on set deduplication and dict key lookup.

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

* Fix pre-existing lint errors in next branch

- test_benchmarks.py: replace append loops with extend (PERF401), add
  @staticmethod to methods that don't use self (PLR6301), suppress
  intentional print calls with noqa: T201
- test_child.py: suppress pylint too-many-lines (C0302)

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Move Huawei VRP tests to integration test directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Rename inconsistent public APIs (#216)

- tags_add()/tags_remove() → add_tags()/remove_tags()
- cisco_style_text() → indented_text()
- dump_simple() → to_lines()
- config_to_get_to() → remediation()
- depth() method → depth property
- Rename private helpers _config_to_get_to/_left/_right accordingly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add custom exception hierarchy (#219) (#239)

Add HierConfigError as the base exception with DriverNotFoundError,
InvalidConfigError, IncompatibleDriverError, and reparent
DuplicateChildError under it. Replace generic ValueError/TypeError
raises in constructors and workflows with specific exception types.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Literal type constraint for indented_text() style parameter (#189) (#241)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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