Skip to content

Commit

Permalink
feat: add a semantic name for internal exception for a better dev exp…
Browse files Browse the repository at this point in the history
…erience on unwrap_or_return + @early_return feature
  • Loading branch information
acostapazo committed Nov 23, 2023
1 parent b0d015d commit 49b1616
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 53 deletions.
2 changes: 1 addition & 1 deletion docs/usage/result.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Returns the encapsulated value if this instance is a success or return Result as
???+ example

Use `unwrap_or_return` in combination with `@early_return` decorator.
If something wrong happens unwrapping your `Result`, the `unwrap_or_return` function will raise an controlled Exception (ReturnErrorOnFailure).
If something wrong happens unwrapping your `Result`, the `unwrap_or_return` function will raise an controlled Exception (`WaitingForEarlyReturn`).
`@early_return` decorator will handle the exception and unwrap the value in case of success.
The following example illustrate this:

Expand Down
4 changes: 2 additions & 2 deletions meiga/decorators/early_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
UnexpectedDecorationOrderError,
)
from meiga.error import Error
from meiga.on_failure_exception import OnFailureException
from meiga.failures import WaitingForEarlyReturn
from meiga.result import Result

P = ParamSpec("P")
Expand All @@ -29,7 +29,7 @@ def _early_return(*args: P.args, **kwargs: P.kwargs) -> R:
return Failure(UnexpectedDecorationOrderError())
else:
return func(*args, **kwargs)
except OnFailureException as exc:
except WaitingForEarlyReturn as exc:
return cast(R, exc.result)
except Error as error:
return cast(R, Failure(error))
Expand Down
24 changes: 24 additions & 0 deletions meiga/failures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import TYPE_CHECKING

from meiga.error import Error

if TYPE_CHECKING:
from meiga.alias import AnyResult


class WaitingForEarlyReturn(Error):
result: "AnyResult"

def __init__(self, result: "AnyResult") -> None:
self.result = result
Exception.__init__(self)

def __str__(self) -> str:
return (
f"This exception wraps the following result -> {self.result}"
f"\nIf you want to handle this error and return a Failure, please use early_return decorator on your function."
f"\nMore info about how to use unwrap_or_return in combination with @early_return decorator on https://alice-biometrics.github.io/meiga/usage/result/#unwrap_or_return"
)

def __repr__(self) -> str:
return str(self)
20 changes: 0 additions & 20 deletions meiga/on_failure_exception.py

This file was deleted.

4 changes: 2 additions & 2 deletions meiga/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
get_on_failure_handler_from_deprecated_args,
get_on_success_handler_from_deprecated_args,
)
from meiga.failures import WaitingForEarlyReturn
from meiga.handlers import OnFailureHandler, OnSuccessHandler
from meiga.no_given_value import NoGivenValue
from meiga.on_failure_exception import OnFailureException

TS = TypeVar("TS") # Success Type
TF = TypeVar("TF") # Failure Type
Expand Down Expand Up @@ -144,7 +144,7 @@ def unwrap_or_return(self, return_value_on_failure: Any = None) -> TS:
return_value = (
self if return_value_on_failure is None else return_value_on_failure
)
raise OnFailureException(return_value)
raise WaitingForEarlyReturn(return_value)
return cast(TS, self.value)

def unwrap_or_throw(self) -> TS:
Expand Down
28 changes: 0 additions & 28 deletions tests/unit/test_on_failure_exception.py

This file was deleted.

30 changes: 30 additions & 0 deletions tests/unit/test_waiting_for_early_return.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest

from meiga import Error, Result
from meiga.failures import WaitingForEarlyReturn


def expected_error(value: str) -> str:
return (
f"This exception wraps the following result -> Result[status: failure | value: {value}]"
f"\nIf you want to handle this error and return a Failure, please use early_return decorator on your function."
f"\nMore info about how to use unwrap_or_return in combination with @early_return decorator on https://alice-biometrics.github.io/meiga/usage/result/#unwrap_or_return"
)


@pytest.mark.unit
class TestWaitingForEarlyReturn:
def should_str_as_expected_default_error(self):
result = Result(failure=Error())

exception = WaitingForEarlyReturn(result)

assert expected_error("Error") == str(exception)

def should_str_as_expected_an_exception(self):
wrapped_exception = ValueError("Something went wrong")
result = Result(failure=wrapped_exception)

exception = WaitingForEarlyReturn(result)

assert expected_error(wrapped_exception.__repr__()) == str(exception)

0 comments on commit 49b1616

Please sign in to comment.