diff --git a/reflex/state.py b/reflex/state.py index e80013418..cb7d3a3f1 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -2053,7 +2053,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow): """ try: return pickle.dumps((self._to_schema(), self)) - except (pickle.PicklingError, AttributeError): + except (pickle.PicklingError, AttributeError) as og_pickle_error: error = ( f"Failed to serialize state {self.get_full_name()} due to unpicklable object. " "This state will not be persisted. " @@ -2063,7 +2063,10 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow): return dill.dumps((self._to_schema(), self)) except ImportError: - error += "Consider `pip install 'dill>=0.3.8'` for more exotic serialization support. " + error += ( + f"Pickle error: {og_pickle_error}. " + "Consider `pip install 'dill>=0.3.8'` for more exotic serialization support." + ) except (pickle.PicklingError, TypeError, ValueError) as ex: error += f"Dill was also unable to pickle the state: {ex}" console.warn(error) diff --git a/tests/units/test_state.py b/tests/units/test_state.py index 23d799f6d..e223b4f19 100644 --- a/tests/units/test_state.py +++ b/tests/units/test_state.py @@ -3360,6 +3360,7 @@ def test_fallback_pickle(): class DillState(BaseState): _o: Obj | None = None _f: Callable | None = None + _g: Any = None state = DillState(_reflex_internal_init=True) # type: ignore state._o = Obj(_f=lambda: 42) @@ -3370,3 +3371,10 @@ def test_fallback_pickle(): unpickled_state = BaseState._deserialize(pk) assert unpickled_state._f() == 420 assert unpickled_state._o._f() == 42 + + # Some object, like generator, are still unpicklable with dill. + state._g = (i for i in range(10)) + pk = state._serialize() + assert len(pk) == 0 + with pytest.raises(EOFError): + BaseState._deserialize(pk)