Move error handling to common
This commit is contained in:
parent
0415ea2560
commit
522d3bc5d9
3 changed files with 30 additions and 43 deletions
|
@ -4,9 +4,11 @@ from typing import Iterable, NamedTuple, Optional
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
import porg
|
import porg
|
||||||
from kython import listify
|
from .common import listify
|
||||||
|
from ..error import Res, echain
|
||||||
|
|
||||||
|
|
||||||
from kython.org import parse_org_date
|
from kython.org import parse_org_date
|
||||||
from kython.kerror import Res, echain
|
|
||||||
|
|
||||||
from mycfg import paths
|
from mycfg import paths
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
from typing import Union, TypeVar, Iterator, Callable, Iterable, List, Tuple, Type
|
"""
|
||||||
|
Various error handling helpers
|
||||||
|
See https://beepb00p.xyz/mypy-error-handling.html#kiss for more detail
|
||||||
|
"""
|
||||||
|
|
||||||
|
from itertools import tee
|
||||||
|
from typing import Union, TypeVar, Iterable, List, Tuple, Type
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
E = TypeVar('E', bound=Exception)
|
E = TypeVar('E', bound=Exception) # TODO make covariant?
|
||||||
|
|
||||||
ResT = Union[T, E]
|
ResT = Union[T, E]
|
||||||
|
|
||||||
Res = ResT[T, Exception]
|
Res = ResT[T, Exception]
|
||||||
|
|
||||||
|
|
||||||
# TODO make it a bit more typed??
|
|
||||||
def is_error(res: Res[T]) -> bool:
|
|
||||||
return isinstance(res, Exception)
|
|
||||||
|
|
||||||
|
|
||||||
def is_ok(res: Res[T]) -> bool:
|
|
||||||
return not is_error(res)
|
|
||||||
|
|
||||||
|
|
||||||
def unwrap(res: Res[T]) -> T:
|
def unwrap(res: Res[T]) -> T:
|
||||||
if isinstance(res, Exception):
|
if isinstance(res, Exception):
|
||||||
raise res
|
raise res
|
||||||
|
@ -25,38 +22,26 @@ def unwrap(res: Res[T]) -> T:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def split_errors(l: Iterable[ResT[T, E]], ET=Exception) -> Tuple[List[T], List[E]]:
|
|
||||||
rl: List[T] = []
|
|
||||||
el: List[E] = []
|
|
||||||
for x in l:
|
|
||||||
if isinstance(x, ET):
|
|
||||||
el.append(x)
|
|
||||||
else:
|
|
||||||
rl.append(x) # type: ignore
|
|
||||||
return rl, el
|
|
||||||
|
|
||||||
|
|
||||||
def ytry(cb) -> Iterator[Exception]:
|
|
||||||
try:
|
|
||||||
cb()
|
|
||||||
except Exception as e:
|
|
||||||
yield e
|
|
||||||
|
|
||||||
|
|
||||||
# TODO experimental, not sure if I like it
|
|
||||||
def echain(ex: E, cause: Exception) -> E:
|
def echain(ex: E, cause: Exception) -> E:
|
||||||
ex.__cause__ = cause
|
ex.__cause__ = cause
|
||||||
# TODO assert cause is none?
|
|
||||||
# TODO copy??
|
|
||||||
return ex
|
return ex
|
||||||
# try:
|
|
||||||
# # TODO is there a awy to get around raise from?
|
|
||||||
# raise ex from cause
|
def split_errors(l: Iterable[ResT[T, E]], ET: Type[E]) -> Tuple[Iterable[T], Iterable[E]]:
|
||||||
# except Exception as e:
|
# TODO would be nice to have ET=Exception default?
|
||||||
# if isinstance(e, type(ex)):
|
vit, eit = tee(l)
|
||||||
# return e
|
# TODO ugh, not sure if I can reconcile type checking and runtime and convince mypy that ET and E are the same type?
|
||||||
# else:
|
values: Iterable[T] = (
|
||||||
# raise e
|
r # type: ignore[misc]
|
||||||
|
for r in vit
|
||||||
|
if not isinstance(r, ET))
|
||||||
|
errors: Iterable[E] = (
|
||||||
|
r
|
||||||
|
for r in eit
|
||||||
|
if isinstance(r, ET))
|
||||||
|
# TODO would be interesting to be able to have yield statement anywehere in code
|
||||||
|
# so there are multiple 'entry points' to the return value
|
||||||
|
return (values, errors)
|
||||||
|
|
||||||
|
|
||||||
def sort_res_by(items: Iterable[ResT], key) -> List[ResT]:
|
def sort_res_by(items: Iterable[ResT], key) -> List[ResT]:
|
|
@ -9,7 +9,7 @@ import pytz
|
||||||
|
|
||||||
from ..common import setup_logger
|
from ..common import setup_logger
|
||||||
|
|
||||||
from ..kython.kerror import ResT, echain, unwrap, sort_res_by
|
from ..error import ResT, echain, unwrap, sort_res_by
|
||||||
from ..kython.konsume import wrap, zoom, ignore
|
from ..kython.konsume import wrap, zoom, ignore
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue