diff --git a/lazy_player/reactive.py b/lazy_player/reactive.py index aa3c5e9..aae3b70 100644 --- a/lazy_player/reactive.py +++ b/lazy_player/reactive.py @@ -1,19 +1,23 @@ from __future__ import annotations +import sys +import traceback from contextvars import ContextVar from typing import Any, Callable, ClassVar, Generic, Self, TypeVar from weakref import WeakSet -__all__ = ["Ref", "Computed", "update_all_computed"] +__all__ = ["Ref", "Computed", "Watcher", "update_all_computed"] T = TypeVar("T") class Ref(Generic[T]): + _error: Exception | None _users: WeakSet[Computed[Any]] _value: T def __init__(self, initial: T): + self._error = None self._value = initial self._users = WeakSet() @@ -24,6 +28,9 @@ class Ref(Generic[T]): if computed is not None: self._users.add(computed) + if self._error is not None: + raise self._error + return self._value @value.setter @@ -47,6 +54,7 @@ class Computed(Ref[T]): _update: Callable[[], T] def __init__(self, update: Callable[[], T]): + self._error = None self._update = update self._users = WeakSet() self.update() @@ -56,6 +64,10 @@ class Computed(Ref[T]): try: self.value = self._update() + self._error = None + except Exception as err: + self._error = err + traceback.print_exception(err, file=sys.stderr) finally: self._stack.reset(token)