1- from typing import Generic , Optional , TypeVar
1+ import json
2+ import pickle # noqa: S403
3+ from functools import partial
4+ from typing import Any , Callable , Dict , Generic , Optional , TypeVar
25
6+ from pydantic import validator
37from pydantic .generics import GenericModel
8+ from typing_extensions import Self
9+
10+ from taskiq .serialization import exception_to_python , prepare_exception
411
512_ReturnType = TypeVar ("_ReturnType" )
613
714
15+ def _json_encoder (value : Any , default : Callable [[Any ], Any ]) -> Any :
16+ if isinstance (value , BaseException ):
17+ return prepare_exception (value , json )
18+
19+ return default (value )
20+
21+
22+ def _json_dumps (value : Any , * , default : Callable [[Any ], Any ], ** kwargs : Any ) -> str :
23+ return json .dumps (value , default = partial (_json_encoder , default = default ), ** kwargs )
24+
25+
826class TaskiqResult (GenericModel , Generic [_ReturnType ]):
927 """Result of a remote task invocation."""
1028
@@ -15,3 +33,37 @@ class TaskiqResult(GenericModel, Generic[_ReturnType]):
1533 log : Optional [str ] = None
1634 return_value : _ReturnType
1735 execution_time : float
36+
37+ error : Optional [BaseException ] = None
38+
39+ class Config :
40+ arbitrary_types_allowed = True
41+ json_dumps = _json_dumps # type: ignore
42+ json_loads = json .loads
43+
44+ def raise_for_error (self ) -> "Self" :
45+ """Raise exception if `error`.
46+
47+ :raises error: task execution exception
48+ :returns: TaskiqResult
49+ """
50+ if self .error is not None :
51+ raise self .error
52+ return self
53+
54+ def __getstate__ (self ) -> Dict [Any , Any ]:
55+ dict = super ().__getstate__ () # noqa: WPS125
56+ vals : Dict [str , Any ] = dict ["__dict__" ]
57+
58+ if "error" in vals and vals ["error" ] is not None :
59+ vals ["error" ] = prepare_exception (
60+ vals ["error" ],
61+ pickle ,
62+ )
63+
64+ return dict
65+
66+ @validator ("error" , pre = True )
67+ @classmethod
68+ def _validate_error (cls , value : Any ) -> Optional [BaseException ]:
69+ return exception_to_python (value )
0 commit comments