-
Notifications
You must be signed in to change notification settings - Fork 201
class ShopifyCli::Result::Failure
Implements a container for wrapping an error value. In many cases, the error value is going to be an exception but other values are fully supported:
Failure
.new(RuntimeError.new("Something went wrong"))
.error # => RuntimeError.new
Failure
.new("Something went wrong")
.error # => "Something went wrong"
Failure
does not support transformations with then
and map
. When any of
these two methods is invoked on a Failure
, the Failure
itself is returned
unless it is rescued from or unwrapped. This enables the caller to build
optimistic transformation chains and defer error handling:
Failure
.new(nil)
.then { |json| JSON.parse(json) } # Ignored
.then(&:with_indifferent_access) # Ignored
.then { |data| data.values_at(:firstname, :lastname) } # Ignored
.unwrap(Person.new("John", "Doe")) # => Person
Alternatively, we could rescue from the error and then proceed with the remaining transformations:
Person = Struct.new(:firstname, :lastname)
Failure
.new(nil)
.then { |json| JSON.parse(json) } # Ignored
.then(&:with_indifferent_access) # Ignored
.rescue { {firstname: "John", lastname: "Doe" }}
.then { |data| data.values_at(:firstname, :lastname) } # Executed
.then { |members| Person.new(*members) } # Executed
.unwrap(nil) # => Person
error
new(error)
initializes a new Failure
from an arbitrary value. In many cases, this value
is going to be an instance of a subclass of Exception
but any type is
supported.
see source
# File lib/shopify-cli/result.rb, line 245
def initialize(error)
@error = error
end
success?()
always returns false
to indicate that this result represents a failure.
see source
# File lib/shopify-cli/result.rb, line 252
def success?
false
end
failure?()
Always returns true
to indicate that this result represents a failure.
see source
# File lib/shopify-cli/result.rb, line 259
def failure?
true
end
value()
raises an ShopifyCli::Result::UnexpectedError
as a
ShopifyCli::Result::Failure
does not carry a success value.
see source
# File lib/shopify-cli/result.rb, line 267
def value
raise UnexpectedFailure
end
map()
is a no-op and simply returns itself. This is essential to skip transformation
steps in a chain once an error has occurred.
see source
# File lib/shopify-cli/result.rb, line 275
def map
self
end
then()
is a no-op and simply returns itself. This is essential to skip transformation
steps in a chain once an error has occurred.
see source
# File lib/shopify-cli/result.rb, line 283
def then
self
end
rescue(&block)
can be used to recover from a failure or produce a new failure with a
different error.
Failure
.new("Something went wrong")
.rescue { |msg| [msg, "but we fixed it!"].join(" "") }
.tap do |result|
result.success? # => true
result.value # => "Something went wrong but we fixed it!"
end
rescue
is opinionated when it comes to the return value of the block. If the
return value is an Exception
– either one that was raised or an instance of
a subclass of Exception
– a Failure
is returned. Any other value results
in a Success
unless the value has been explicitly wrapped in a Failure
:
Failure
.new(RuntimeError.new)
.rescue { "All good! "}
.success? # => true
Failure
.new(RuntimeError.new)
.rescue { Failure.new("Still broken!") }
.success? # => false
see source
# File lib/shopify-cli/result.rb, line 315
def rescue(&block)
Result.wrap(&block).call(@error)
end
unwrap(*args, &block)
returns the fallback value specified by the caller. The fallback value can be
provided as a method argument or as a block. If a block is given, it receives
the error as its first and only argument:
failure = Failure.new(RuntimeError.new("Something went wrong!"))
failure.unwrap(nil) # => nil
failure.unwrap { |e| e.message } # => "Something went wrong!"
-
*args
should be anArray
with zero or one element -
&block
should be a Proc that takes zero or one argument
-
ArgumentError
if both a fallback argument and a block is provided
see source
# File lib/shopify-cli/result.rb, line 338
def unwrap(*args, &block)
raise ArgumentError, "expected either a fallback value or a block" unless (args.length == 1) ^ block
block ? block.call(@error) : args.pop
end