|
26 | 26 | from collections.abc import Iterator |
27 | 27 | from enum import Enum |
28 | 28 | from functools import wraps |
29 | | -from typing import Any, Callable, Optional, Tuple |
| 29 | +from typing import Any, Callable, List, Optional, Tuple |
30 | 30 | from uuid import UUID |
31 | 31 |
|
32 | 32 | # isort: THIRDPARTY |
|
36 | 36 | from justbytes import Range |
37 | 37 |
|
38 | 38 | # isort: FIRSTPARTY |
39 | | -from dbus_python_client_gen import DPClientInvocationError |
| 39 | +from dbus_python_client_gen import DPClientInvocationError, DPClientMethodCallContext |
40 | 40 |
|
41 | 41 | from .._errors import ( |
42 | 42 | StratisCliKeyfileNotFoundError, |
@@ -315,23 +315,44 @@ def get_errors(exc: BaseException) -> Iterator[BaseException]: |
315 | 315 | exc = exc.__cause__ |
316 | 316 |
|
317 | 317 |
|
318 | | -def long_running_operation(func: Callable) -> Callable: |
| 318 | +def long_running_operation( |
| 319 | + *, method_names: List[str] |
| 320 | +) -> Callable[[Callable], Callable]: |
319 | 321 | """ |
320 | 322 | Mark a function as a long running operation and catch and ignore NoReply |
321 | | - D-Bus exception. |
| 323 | + D-Bus exception so long as the method raising the exception is one |
| 324 | + of the methods specified in method_names. |
322 | 325 | """ |
323 | 326 |
|
324 | | - @wraps(func) |
325 | | - def wrapper(namespace: Namespace): |
326 | | - try: |
327 | | - func(namespace) |
328 | | - except DPClientInvocationError as err: |
329 | | - if not any( |
330 | | - isinstance(e, DBusException) |
331 | | - and e.get_dbus_name() == "org.freedesktop.DBus.Error.NoReply" |
332 | | - for e in get_errors(err) |
333 | | - ): |
| 327 | + def decorator(func: Callable) -> Callable: |
| 328 | + """ |
| 329 | + Decorator |
| 330 | + """ |
| 331 | + |
| 332 | + @wraps(func) |
| 333 | + def wrapper(namespace: Namespace): |
| 334 | + """ |
| 335 | + Wrapper |
| 336 | + """ |
| 337 | + try: |
| 338 | + func(namespace) |
| 339 | + except DPClientInvocationError as err: |
| 340 | + if not any( |
| 341 | + isinstance(e, DBusException) |
| 342 | + and e.get_dbus_name() == "org.freedesktop.DBus.Error.NoReply" |
| 343 | + for e in get_errors(err) |
| 344 | + ): |
| 345 | + raise err |
| 346 | + |
| 347 | + context = err.context |
| 348 | + if ( |
| 349 | + isinstance(context, DPClientMethodCallContext) |
| 350 | + and context.method_name in method_names |
| 351 | + ): |
| 352 | + print("Operation initiated", file=sys.stderr) |
| 353 | + |
334 | 354 | raise err |
335 | | - print("Operation initiated", file=sys.stderr) |
336 | 355 |
|
337 | | - return wrapper |
| 356 | + return wrapper |
| 357 | + |
| 358 | + return decorator |
0 commit comments