Skip to content

Commit 367c1d3

Browse files
author
Maphey
committed
added op as init param for JsonPatchException
1 parent a9a83b5 commit 367c1d3

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

jsonpatch.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@
7474
class JsonPatchException(Exception):
7575
"""Base Json Patch exception"""
7676

77+
def __init__(self, op=None):
78+
"""
79+
Initialize a new instance of a JsonPatchException
80+
:param op: The operation that failed. Attach to exception if you
81+
desire to catch and modify the original patch operations.
82+
:type op: Type[PatchOperation]
83+
"""
84+
self.op = op
85+
7786

7887
class InvalidJsonPatch(JsonPatchException):
7988
""" Raised if an invalid JSON Patch is created """
@@ -238,7 +247,7 @@ def apply(self, obj):
238247
del subobj[part]
239248
except (KeyError, IndexError) as ex:
240249
msg = "can't remove a non-existent object '{0}'".format(part)
241-
raise JsonPatchConflict(msg)
250+
raise JsonPatchConflict(msg, op=self)
242251

243252
return obj
244253

@@ -267,7 +276,7 @@ def apply(self, obj):
267276
value = self.operation["value"]
268277
except KeyError as ex:
269278
raise InvalidJsonPatch(
270-
"The operation does not contain a 'value' member")
279+
"The operation does not contain a 'value' member", op=self)
271280

272281
subobj, part = self.pointer.to_last(obj)
273282

@@ -276,7 +285,7 @@ def apply(self, obj):
276285
subobj.append(value) # pylint: disable=E1103
277286

278287
elif part > len(subobj) or part < 0:
279-
raise JsonPatchConflict("can't insert outside of list")
288+
raise JsonPatchConflict("can't insert outside of list", op=self)
280289

281290
else:
282291
subobj.insert(part, value) # pylint: disable=E1103
@@ -291,7 +300,7 @@ def apply(self, obj):
291300
if part is None:
292301
raise TypeError("invalid document type {0}".format(type(subobj)))
293302
else:
294-
raise JsonPatchConflict("unable to fully resolve json pointer {0}, part {1}".format(self.location, part))
303+
raise JsonPatchConflict("unable to fully resolve json pointer {0}, part {1}".format(self.location, part), op=self)
295304
return obj
296305

297306
def _on_undo_remove(self, path, key):
@@ -319,29 +328,29 @@ def apply(self, obj):
319328
value = self.operation["value"]
320329
except KeyError as ex:
321330
raise InvalidJsonPatch(
322-
"The operation does not contain a 'value' member")
331+
"The operation does not contain a 'value' member", op=self)
323332

324333
subobj, part = self.pointer.to_last(obj)
325334

326335
if part is None:
327336
return value
328337

329338
if part == "-":
330-
raise InvalidJsonPatch("'path' with '-' can't be applied to 'replace' operation")
339+
raise InvalidJsonPatch("'path' with '-' can't be applied to 'replace' operation", op=self)
331340

332341
if isinstance(subobj, MutableSequence):
333342
if part >= len(subobj) or part < 0:
334-
raise JsonPatchConflict("can't replace outside of list")
343+
raise JsonPatchConflict("can't replace outside of list", op=self)
335344

336345
elif isinstance(subobj, MutableMapping):
337346
if part not in subobj:
338347
msg = "can't replace a non-existent object '{0}'".format(part)
339-
raise JsonPatchConflict(msg)
348+
raise JsonPatchConflict(msg, op=self)
340349
else:
341350
if part is None:
342351
raise TypeError("invalid document type {0}".format(type(subobj)))
343352
else:
344-
raise JsonPatchConflict("unable to fully resolve json pointer {0}, part {1}".format(self.location, part))
353+
raise JsonPatchConflict("unable to fully resolve json pointer {0}, part {1}".format(self.location, part), op=self)
345354

346355
subobj[part] = value
347356
return obj
@@ -364,21 +373,21 @@ def apply(self, obj):
364373
from_ptr = self.pointer_cls(self.operation['from'])
365374
except KeyError as ex:
366375
raise InvalidJsonPatch(
367-
"The operation does not contain a 'from' member")
376+
"The operation does not contain a 'from' member", op=self)
368377

369378
subobj, part = from_ptr.to_last(obj)
370379
try:
371380
value = subobj[part]
372381
except (KeyError, IndexError) as ex:
373-
raise JsonPatchConflict(str(ex))
382+
raise JsonPatchConflict(str(ex), op=self)
374383

375384
# If source and target are equal, this is a no-op
376385
if self.pointer == from_ptr:
377386
return obj
378387

379388
if isinstance(subobj, MutableMapping) and \
380389
self.pointer.contains(from_ptr):
381-
raise JsonPatchConflict('Cannot move values into their own children')
390+
raise JsonPatchConflict('Cannot move values into their own children', op=self)
382391

383392
obj = RemoveOperation({
384393
'op': 'remove',
@@ -450,18 +459,18 @@ def apply(self, obj):
450459
else:
451460
val = self.pointer.walk(subobj, part)
452461
except JsonPointerException as ex:
453-
raise JsonPatchTestFailed(str(ex))
462+
raise JsonPatchTestFailed(str(ex), op=self)
454463

455464
try:
456465
value = self.operation['value']
457466
except KeyError as ex:
458467
raise InvalidJsonPatch(
459-
"The operation does not contain a 'value' member")
468+
"The operation does not contain a 'value' member", op=self)
460469

461470
if val != value:
462471
msg = '{0} ({1}) is not equal to tested value {2} ({3})'
463472
raise JsonPatchTestFailed(msg.format(val, type(val),
464-
value, type(value)))
473+
value, type(value)), op=self)
465474

466475
return obj
467476

@@ -474,13 +483,13 @@ def apply(self, obj):
474483
from_ptr = self.pointer_cls(self.operation['from'])
475484
except KeyError as ex:
476485
raise InvalidJsonPatch(
477-
"The operation does not contain a 'from' member")
486+
"The operation does not contain a 'from' member", op=self)
478487

479488
subobj, part = from_ptr.to_last(obj)
480489
try:
481490
value = copy.deepcopy(subobj[part])
482491
except (KeyError, IndexError) as ex:
483-
raise JsonPatchConflict(str(ex))
492+
raise JsonPatchConflict(str(ex), op=self)
484493

485494
obj = AddOperation({
486495
'op': 'add',
@@ -672,15 +681,15 @@ def apply(self, obj, in_place=False):
672681

673682
def _get_operation(self, operation):
674683
if 'op' not in operation:
675-
raise InvalidJsonPatch("Operation does not contain 'op' member")
684+
raise InvalidJsonPatch("Operation does not contain 'op' member", op=operation)
676685

677686
op = operation['op']
678687

679688
if not isinstance(op, basestring):
680-
raise InvalidJsonPatch("Operation must be a string")
689+
raise InvalidJsonPatch("Operation must be a string", op=operation)
681690

682691
if op not in self.operations:
683-
raise InvalidJsonPatch("Unknown operation {0!r}".format(op))
692+
raise InvalidJsonPatch("Unknown operation {0!r}".format(op), op=operation)
684693

685694
cls = self.operations[op]
686695
return cls(operation, pointer_cls=self.pointer_cls)

0 commit comments

Comments
 (0)