Skip to content

feat: add --suppress CLI flag + suppress_error_codes filter (PR 6 of 6) - #180

Merged
azoner merged 1 commit into
masterfrom
feat/error-codes-suppress-pr6
May 6, 2026
Merged

feat: add --suppress CLI flag + suppress_error_codes filter (PR 6 of 6)#180
azoner merged 1 commit into
masterfrom
feat/error-codes-suppress-pr6

Conversation

@azoner

@azoner azoner commented May 6, 2026

Copy link
Copy Markdown
Owner

Sixth and final slice of the X12 error code generalization plan. Now that every producer emits pyx12 codes (PRs #176-#178) and the legacy fallback is gone (PR #179), suppression by pyx12 code is straightforward: filter at the apply_segment_errors / apply_walk_errors bridge before errors reach the err_handler tree. Suppressed errors never appear in the 997/999 ack, the JSON output, or the tree's get_error_count.

What's in this PR

pyx12/params.py — new default setting suppress_error_codes = set(). Populate programmatically via params.set(\"suppress_error_codes\", {...}) or via --suppress on the CLI.

pyx12/error_handler.py — new field suppress_error_codes: set[str] on err_handler / errh_null / errh_list, default empty set. Bridges read it via getattr to stay decoupled.

Bridge filtering:

  • pyx12/map_if/_segment.py apply_segment_errors: drops errors whose err_cde is in errh.suppress_error_codes before dispatching to errh.seg_error / errh.ele_error. ok still reflects whether the validator found errors (suppression doesn't flip a bad segment to good).
  • pyx12/map_walker.py apply_walk_errors: same shape.

Orchestrator wiring:

  • pyx12/x12n_document.py: copies params.suppress_error_codes onto the err_handler instance before parsing.
  • pyx12/x12context.py: same wiring for the X12ContextReader path.

CLI:

x12valid --suppress ELE_6_invalid_composite,SEG_3_too_many_elements -- f.x12
x12valid -S ELE_6_invalid_composite -S SEG_3_too_many_elements -- f.x12

Tests

SuppressErrorCodes class (3 tests):

  • Suppression removes element error from 999 ack (no IK4 segment)
  • Suppression removes element error from JSON output
  • Suppressing an unrelated code is a no-op (output byte-identical)

SuppressCLIArg class (3 tests):

  • Single code via argparse
  • Comma-separated codes
  • Repeated flag

Test plan

  • pytest pyx12/test/: 587 passed (581 baseline + 6 new suppression tests)
  • mypy --strict pyx12: clean (88 files)
  • ruff check + format --check: clean

Plan reference

~/.claude/plans/radiant-petting-steele.md — see PR 6 section.

End state of the refactor

After this PR lands, the X12 error code generalization is complete:

  • ~50 named pyx12 codes covering element / composite / segment levels
  • One source of truth (pyx12.error_codes.ERROR_CODES) for code → X12 (AK/IK) mapping
  • Granular suppression by pyx12 code via --suppress
  • JSON output carries both err_cde (pyx12 code) and x12_code (X12-spec code) for downstream consumers
  • 997 / 999 ack output unchanged (visitors translate at output time)

🤖 Generated with Claude Code

Sixth and final slice of the X12 error code generalization plan. Now
that every producer emits pyx12 codes (PRs 2-4) and the legacy
fallback is gone (PR 5), suppression by pyx12 code is straightforward:
filter at the apply_segment_errors / apply_walk_errors bridge before
errors reach the err_handler tree. Suppressed errors never appear in
the 997/999 ack, the JSON output, or the tree's get_error_count.

What's new:

pyx12/params.py:
- New default setting `suppress_error_codes = set()`. Populated via
  `params.set("suppress_error_codes", {"ELE_6_invalid_type_char", ...})`
  programmatically or via `--suppress` on the CLI.

pyx12/error_handler.py:
- New field `suppress_error_codes: set[str]` on err_handler / errh_null
  / errh_list, default empty set. Bridges read it via getattr to stay
  decoupled from the err_handler subclass.

Bridge filtering:
- pyx12/map_if/_segment.py apply_segment_errors: drops errors whose
  err_cde is in errh.suppress_error_codes before dispatching to
  errh.seg_error / errh.ele_error. ok still reflects whether the
  validator found errors (suppression doesn't flip a bad segment to good).
- pyx12/map_walker.py apply_walk_errors: same shape.

Orchestrator wiring:
- pyx12/x12n_document.py: copies params.suppress_error_codes onto the
  err_handler instance before parsing.
- pyx12/x12context.py: same wiring for the X12ContextReader path.

CLI:
- pyx12/scripts/x12valid.py: new -S / --suppress flag. Comma-separated
  codes; can be repeated. Example:
    x12valid --suppress ELE_6_invalid_composite,SEG_3_too_many_elements -- f.x12

Tests:
- SuppressErrorCodes class in test_x12n_document.py with 3 tests:
  * suppression removes the element error from the 999 ack (no IK4)
  * suppression removes the element error from JSON output
  * suppressing an unrelated code is a no-op (output identical)
- SuppressCLIArg class with 3 argparse-level tests (single code,
  comma-separated, repeated flag)

Verification:
- pytest pyx12/test/: 587 passed (581 + 6 new suppression tests)
- mypy --strict pyx12: clean (88 files)
- ruff check + format --check: clean

This completes the X12 error code generalization work. Producers emit
pyx12 codes throughout; visitors translate via the ERROR_CODES table
at output time; CLI / params expose granular suppression. End state:
- ~50 named pyx12 codes covering element / composite / segment levels
- One source of truth (pyx12.error_codes.ERROR_CODES) for code →
  X12 (AK/IK) mapping
- Granular suppression by code

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@azoner
azoner merged commit 9157a9e into master May 6, 2026
16 checks passed
@azoner
azoner deleted the feat/error-codes-suppress-pr6 branch May 6, 2026 13:22
azoner added a commit that referenced this pull request May 6, 2026
The X12 error code generalization (PRs #175-#180) introduced a pyx12
internal code namespace (ELE_*, COMP_*, SEG_*) that is now what
producers emit and what suppression accepts. The X12 numeric codes
(AK4 / IK4 / AK3 / IK3) only appear in the 997/999 ack output and the
JSON x12_code field.

Update docs/errors.rst:

- Reframe the intro to explain the pyx12 code -> X12 code translation
  layer; point at pyx12.error_codes and ERROR_CODES.
- Replace the legacy "Element-level codes (AK4 / IK4)" and
  "Segment-level codes (AK3 / IK3)" tables (which listed raw X12 codes
  the err_handler tree no longer carries at those levels) with a
  comprehensive pyx12-codes-first reference: every entry in
  ERROR_CODES with its level, AK code, IK code, and meaning. Codes
  with no ack output (HL1/HL2/LX historical "filter out" behavior)
  show "—" in the AK/IK columns.
- Note the apply_segment_errors behavior: validator-level seg codes
  route through seg_error with a hardcoded "8" for X12 spec correctness
  per PR #161.
- Update the worked example to use a pyx12 code
  (SEG_5_segment_repeat_exceeded) and explicitly link the pyx12 ->
  X12 mapping.
- Update the "Reading errors from Python" section to show that the
  err_seg / err_ele lists carry pyx12 codes while ISA/GS/ST envelope
  errors are still raw X12 strings; add a short example of using
  ERROR_CODES and x12_code_for from user code.
- Add a "Suppressing codes" section covering the new --suppress /
  -S CLI flag and the params.set("suppress_error_codes", ...)
  programmatic alternative.

Keep the existing transaction-set / functional-group / interchange
code tables intact — those envelope-level codes (TA1, AK5, AK9) are
not migrated to pyx12 codes (out of scope of the refactor).

Co-Authored-By: Claude Opus 4.7 <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.

1 participant