Project

errant

0.0
Repository is archived
No commit activity in last 3 years
No release in over 3 years
An implementation of "monadic," or "railway-oriented," error handling for Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 1.9
~> 10.0
 Project Readme

Errant

An implementation of Railway-Oriented Programming for Ruby.

Usage

capturing

You can use Errant to capture and wrap exceptions in the natural flow of your code. If an exception is expected, after all, it's not really an exception; it's a value which you are anticipating and can deal with. This style uses the capturing method:

x = Errant.capturing(StandardError) { 35 }
# => #<Errant::Success:0x000000011136f8 @exceptions=[StandardError], @value=35>

x = x.flat_map { |n| n * 2 }
# => #<Errant::Success:0x000000018eab10 @exceptions=[StandardError], @value=70>

x = x.flat_map { fail "Oops! }
# => #<Errant::Failure:0x000000018bad48 @value=#<RuntimeError: oops!>>

If you specify a list of exceptions in your call to capturing, exceptions which don't fit in that list will be raised as usual.

x = Errant.capturing(ArgumentError) { 35 }
# => #<Errant::Success:0x000000011136f8 @exceptions=[StandardError], @value=35>

x = x.flat_map { fail "Oops!" }
# RuntimeError:  oops

Direct Instantiation

You can also use Errant to explicitly return Success and Failure objects. For conciseness, this utilizes the [] methods, and should generally be preferred to capturing when the logical branching necessary to determine success or failure is complex. For example, a successful value might look like this:

x = Errant::Success[35]
# => #<Errant::Success:0x000000011136f8 @exceptions=[StandardError], @value=35>

You can also instantiate failures directly:

x = Errant::Failure["missing vital data"]
# => #<Errant::Failure:0x000000018a7568 @value="missing vital data">

Working With Values

The flat_map method should be favored when working with wrapped values. It is equivalent to the >>= (bind) operator in Haskell, or flatMap in Scala.

x = Errant::Success[5]
  .flat_map { |n| n * 2 }
  .flat_map { |n| n * 5 }
  .flat_map { |n| n.to_s + "!" }

flat_map, called on an Error value, will do nothing.