Skip to content
Pyrula

Try

Try runs a function and captures the result: Success(value) if it returned, Failure(exc) if it raised. Use it to pull an exception out of control flow and into a value you can pass around.

from pyrula import Try
Try.apply(lambda: int("42")) # Success(42)
Try.apply(lambda: int("nope")) # Failure(ValueError(...))
result = Try.apply(lambda: int(user_input))
result.map(lambda n: n * 2).get_or_else(0)
result.fold(
lambda exc: f"bad input: {exc}",
lambda n: f"got {n}",
)
result.recover(lambda exc: 0) # Failure becomes Success(0)

map and flat_map only run on Success. A Failure carries its exception through untouched until you handle it with fold, recover, or get_or_else.

to_either() converts to an Either when you’d rather carry a typed error than the raw exception.

Reach for Try when the failure is an exception you didn’t choose (a parse, a library call). Reach for Either when you decide what counts as an error and want a specific error value, not an exception object.

Try[A] is a real generic alias. Success and Failure are both subtypes of Try, so isinstance(x, Try) holds for both cases and type checkers can narrow correctly:

from pyrula import Try, Success, Failure
def parse(s: str) -> Try[int]:
return Try.apply(lambda: int(s))
result = parse("42")
assert isinstance(result, Try) # True for both cases
assert isinstance(result, Success)

Scala’s scala.util.Try: Success/Failure, with the same map, flat_map, recover, fold, and to_either (toEither). Try.apply(lambda: ...) is Scala’s Try { ... }.