fork download
  1.  
  2.  
  3. def handle(exception, callback):
  4. def inner(wrapped):
  5. def f(self, *args, **kwargs):
  6. try:
  7. return wrapped(self, *args, **kwargs)
  8. except exception as exc:
  9. callback(self)
  10. self.rollback()
  11. return 'retry' # enum action result retry value
  12. return f
  13. return inner
  14.  
  15.  
  16. def print_action(msg, action):
  17. print(msg.format(action=action.__class__.__name__))
  18.  
  19.  
  20. class Action:
  21.  
  22. def run(self):
  23. pass
  24.  
  25. def rollback(self):
  26. print_action('Rolling back {action}', self)
  27.  
  28.  
  29. class A1(Action):
  30.  
  31. def run(self):
  32. print_action('Running {action}', self)
  33.  
  34.  
  35. class A2(A1):
  36.  
  37. @handle(
  38. RuntimeError,
  39. lambda action: print_action('Handle RuntimeError for action {action}', action)
  40. )
  41. def run(self):
  42. raise RuntimeError()
  43.  
  44. class A3(A2):
  45.  
  46. @handle(
  47. ValueError,
  48. lambda action: print_action('Handle ValueError for action {action}', action)
  49. )
  50. @handle(
  51. IndexError,
  52. lambda action: print_action('Handle IndexError for action {action}', action)
  53. )
  54. def run(self):
  55. raise ValueError()
  56.  
  57.  
  58. a1 = A1()
  59. a1.run()
  60.  
  61. a2 = A2()
  62. a2.run()
  63.  
  64. a3 = A3()
  65. a3.run()
  66.  
  67.  
Success #stdin #stdout 0.02s 8984KB
stdin
Standard input is empty
stdout
Running A1
Handle RuntimeError for action A2
Rolling back A2
Handle ValueError for action A3
Rolling back A3