diff --git a/tests/test_result.py b/tests/test_result.py index 12335f8..b64ad14 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -87,6 +87,38 @@ async def test_err_unwraps() -> None: ) +@pytest.mark.parametrize("error", [ValueError("err"), KeyboardInterrupt()]) +async def test_err_unwrap_preserves_underlying_exception(error: BaseException) -> None: + try: + raise error + except BaseException: + pass + + underlying_traceback = error.__traceback__ + assert underlying_traceback is not None + + result = Err(error) + + with pytest.raises(ErrUnwrapError, match="on err") as exc_info: + result.unwrap(on_err="on err") + + assert exc_info.value.__cause__ is error + assert exc_info.value.__cause__.__traceback__ is underlying_traceback + + with pytest.raises(ErrUnwrapError) as future_exc_info: + await FutureResult.from_(result).unwrap() + + assert future_exc_info.value.__cause__ is error + assert future_exc_info.value.__cause__.__traceback__ is underlying_traceback + + +def test_err_unwrap_does_not_chain_non_exception_value() -> None: + with pytest.raises(ErrUnwrapError) as exc_info: + Err("err").unwrap() + + assert exc_info.value.__cause__ is None + + @pytest.mark.parametrize( ("result", "target"), [ diff --git a/wird/_result.py b/wird/_result.py index f202eda..3c8d992 100644 --- a/wird/_result.py +++ b/wird/_result.py @@ -689,7 +689,10 @@ def unwrap[R]( def unwrap(self, *, on_err: str = "expected Ok, got Err") -> Any: ... def unwrap(self, **kwargs) -> Any: - raise ErrUnwrapError(kwargs.get("on_err", "expected Ok, got Err")) + error = ErrUnwrapError(kwargs.get("on_err", "expected Ok, got Err")) + if isinstance(self.internal, BaseException): + raise error from self.internal + raise error def unwrap_or[T](self, /, other: T) -> T: return other