Skip to content

Attach failing operation to JsonPatchException as op - #247

Merged
stefankoegl merged 2 commits into
masterfrom
claude/confident-curie-9x5ahd
Nov 2, 2026
Merged

stefankoegl merged 2 commits into
masterfrom
claude/confident-curie-9x5ahd

Conversation

@stefankoegl

@stefankoegl stefankoegl commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

Supersedes #126 (originally by sammaphey), re-applied on top of current master.

Changes

  • JsonPatchException accepts an optional op keyword argument and exposes it as exc.op (defaults to None, so existing callers are unaffected).
  • Every JsonPatchException (InvalidJsonPatch, JsonPatchConflict, JsonPatchTestFailed) raised by this library while constructing or applying a patch carries the failing operation:
    • the PatchOperation instance for errors raised from an operation's methods (apply, _from_pointer);
    • for move and copy, the enclosing MoveOperation / CopyOperation, also when the failure happens in the internal remove/add step they delegate to;
    • the raw operation object for errors raised before an operation could be constructed (PatchOperation.__init__, JsonPatch._get_operation, and string entries rejected in JsonPatch.__init__).

Out of scope

JsonPointerException raised by the jsonpointer library (e.g. a path not starting with /, or a pointer that cannot be resolved against the document) is not a JsonPatchException subclass and is left unchanged — it does not have an op attribute. Converting those into JsonPatchExceptions would change which exceptions callers see and is better handled in a separate PR.

Difference from #126

The original constructor was __init__(self, op=None), so JsonPatchConflict(msg, op=self) raised TypeError: got multiple values for argument 'op', and the message never reached Exception. The new constructor pops op from kwargs and forwards the remaining args to Exception.__init__.

Tests

ExceptionOperationTests covers: conflict, failed test operation, invalid operation carrying the raw dict, string entry carrying the raw string, move failing in its add and remove steps, copy failing in its add step, and op defaulting to None. pytest: 255 passed; python tests.py: OK.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PewzpkvyJUvFMnnjKxmyNd

Brings #126 up to date with current master. JsonPatchException now
accepts an optional `op` keyword argument, and all exceptions raised
while constructing or applying a patch operation carry the failing
operation (the PatchOperation instance, or the raw operation dict if
it could not be constructed).

Compared to the original PR, the constructor now forwards the message
to Exception, which fixes a TypeError ("got multiple values for
argument 'op'") when raising with both a message and op. Tests added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PewzpkvyJUvFMnnjKxmyNd
@coveralls

coveralls commented Nov 2, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 100.0%. remained the same — claude/confident-curie-9x5ahd into master

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Exception attribution remains incomplete: delegated move/copy failures report synthetic operations, while rejected string entries leave op unset, preventing callers from reliably identifying the original failing operation.

2 open issues
What changed in this PR

Adds operation context to JSON Patch exceptions so callers can inspect the failing operation while preserving existing exception messages.

Changes:

  • Adds an optional op argument and attribute to JsonPatchException.
  • Attaches operation instances or raw operation objects at exception sites.
  • Adds regression tests for operation context, message preservation, and the default None value.
File Description
tests.py Adds exception-context tests and registers them in the test suite.
jsonpatch.py Extends the base exception and attaches operation context to patch errors.

Review effort: Balanced

Comment thread jsonpatch.py Resolved
Comment thread jsonpatch.py Resolved
…tion

- MoveOperation and CopyOperation delegate to internal, synthetic
  RemoveOperation / AddOperation instances. Exceptions raised by those
  now have `op` set to the enclosing move/copy operation, so callers
  can identify the operation that is actually part of the patch.
- The "sequence of strings" check in JsonPatch.__init__ now attaches
  the offending entry as `op`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PewzpkvyJUvFMnnjKxmyNd

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

JSON-pointer exceptions during construction and application still lack the raw operation context, leaving the stated exception-context guarantee unmet.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity JSON-pointer exceptions omit operation context

jsonpatch.py:199

JSON-pointer errors still escape without op: constructing {'op': 'add', 'path': 'foo', 'value': 1} raises JsonPointerException without the raw operation, and pointer-resolution failures during application also bypass these annotations. This leaves the description's guarantee of operation context on every construction/application exception unmet. Either attach the operation when re-raising pointer exceptions, preserving their existing type, or narrow the stated guarantee to JsonPatchException subclasses.

2 resolved since last review

Review effort: Balanced

@stefankoegl
stefankoegl merged commit 20bfe05 into master Nov 2, 2026
21 of 22 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.

4 participants