You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Attach failing operation to JsonPatchException as op - #247
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.
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.
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
…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
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #126 (originally by sammaphey), re-applied on top of current master.
Changes
JsonPatchExceptionaccepts an optionalopkeyword argument and exposes it asexc.op(defaults toNone, so existing callers are unaffected).JsonPatchException(InvalidJsonPatch,JsonPatchConflict,JsonPatchTestFailed) raised by this library while constructing or applying a patch carries the failing operation:PatchOperationinstance for errors raised from an operation's methods (apply,_from_pointer);moveandcopy, the enclosingMoveOperation/CopyOperation, also when the failure happens in the internal remove/add step they delegate to;PatchOperation.__init__,JsonPatch._get_operation, and string entries rejected inJsonPatch.__init__).Out of scope
JsonPointerExceptionraised by thejsonpointerlibrary (e.g. apathnot starting with/, or a pointer that cannot be resolved against the document) is not aJsonPatchExceptionsubclass and is left unchanged — it does not have anopattribute. Converting those intoJsonPatchExceptions 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), soJsonPatchConflict(msg, op=self)raisedTypeError: got multiple values for argument 'op', and the message never reachedException. The new constructor popsopfrom kwargs and forwards the remaining args toException.__init__.Tests
ExceptionOperationTestscovers: conflict, failedtestoperation, invalid operation carrying the raw dict, string entry carrying the raw string,movefailing in its add and remove steps,copyfailing in its add step, andopdefaulting toNone.pytest: 255 passed;python tests.py: OK.🤖 Generated with Claude Code
https://claude.ai/code/session_01PewzpkvyJUvFMnnjKxmyNd