Class: FService::Result::Failure

Inherits:
Base
  • Object
show all
Defined in:
lib/f_service/result/failure.rb

Overview

Represents a value of a failed operation. The error field can contain any information you want.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#on_failure, #on_success, #to_ary, #type

Constructor Details

#initialize(error, types = []) ⇒ Failure

Creates a failed operation. You usually shouldn’t call this directly. See Base#Failure.

Parameters:

  • error (Object)

    failure value.



23
24
25
26
# File 'lib/f_service/result/failure.rb', line 23

def initialize(error, types = [])
  super(types)
  @error = error
end

Instance Attribute Details

#errorObject (readonly)

Returns the provided error for the result.

Returns:

  • (Object)

    the provided error for the result



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/f_service/result/failure.rb', line 16

class Failure < Result::Base
  attr_reader :error

  # Creates a failed operation.
  # You usually shouldn't call this directly. See {FService::Base#Failure}.
  #
  # @param error [Object] failure value.
  def initialize(error, types = [])
    super(types)
    @error = error
  end

  # Returns false.
  #
  #
  # @example
  #   # Suppose that User::Update returns an FService::Result
  #
  #   log_errors(user) unless User::Update.(user: user).successful?
  def successful?
    false
  end

  # Returns true.
  #
  #
  # @example
  #   # Suppose that User::Update returns an FService::Result
  #
  #   log_errors(user) if User::Update.(user: user).failed?
  def failed?
    true
  end

  # Failed operations do not have value.
  def value
    nil
  end

  # Raises an exception if called.
  # (see #value)
  def value!
    raise Result::Error, 'Failure objects do not have value'
  end

  # Returns the current error to the given block.
  # Use this to chain multiple service calls (since all services return Results).
  # It works just like the `.and_then` method, but only runs if the result is a Failure.
  #
  #
  # @example
  #   class UpdateUserOnExternalService
  #     attribute :user_params
  #
  #     def run
  #       check_api_status
  #         .and_then { update_user }
  #         .or_else { create_update_worker }
  #     end
  #
  #     private
  #     # some code
  #   end
  #
  # @yieldparam error pass {#error} to a block
  # @yieldparam type pass {#type} to a block
  def catch
    yield(*to_ary)
  end

  alias or_else catch

  # Returns itself to the given block.
  # Use this to chain multiple service calls (since all services return Results).
  # It will short circuit your service call chain.
  #
  #
  # @example
  #   class UsersController < BaseController
  #     def create
  #       result = User::Create.(user_params) # if this fails the following calls won't run
  #                            .and_then { |user| User::SendWelcomeEmail.(user: user) }
  #                            .and_then { |user| User::Login.(user: user) }
  #
  #       if result.successful?
  #         json_success(result.value)
  #       else
  #         json_error(result.error)
  #       end
  #     end
  #   end
  #
  # @return [self]
  def and_then
    self
  end

  # See #and_then
  def then
    FService.deprecate!(name: "#{self.class}##{__method__}", alternative: '#and_then', from: caller[0])
    and_then
  end

  # Outputs a string representation of the object
  #
  #
  # @example
  #   puts FService::Result::Failure.new("Oh no!")
  #   # => Failure("Oh no!")
  #
  # @return [String] the object's string representation
  def to_s
    error.nil? ? 'Failure()' : "Failure(#{error.inspect})"
  end
end

#typesObject (readonly)

Returns the provided types for the result. Defaults to nil.

Returns:

  • (Object)

    the provided types for the result. Defaults to nil.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/f_service/result/failure.rb', line 16

class Failure < Result::Base
  attr_reader :error

  # Creates a failed operation.
  # You usually shouldn't call this directly. See {FService::Base#Failure}.
  #
  # @param error [Object] failure value.
  def initialize(error, types = [])
    super(types)
    @error = error
  end

  # Returns false.
  #
  #
  # @example
  #   # Suppose that User::Update returns an FService::Result
  #
  #   log_errors(user) unless User::Update.(user: user).successful?
  def successful?
    false
  end

  # Returns true.
  #
  #
  # @example
  #   # Suppose that User::Update returns an FService::Result
  #
  #   log_errors(user) if User::Update.(user: user).failed?
  def failed?
    true
  end

  # Failed operations do not have value.
  def value
    nil
  end

  # Raises an exception if called.
  # (see #value)
  def value!
    raise Result::Error, 'Failure objects do not have value'
  end

  # Returns the current error to the given block.
  # Use this to chain multiple service calls (since all services return Results).
  # It works just like the `.and_then` method, but only runs if the result is a Failure.
  #
  #
  # @example
  #   class UpdateUserOnExternalService
  #     attribute :user_params
  #
  #     def run
  #       check_api_status
  #         .and_then { update_user }
  #         .or_else { create_update_worker }
  #     end
  #
  #     private
  #     # some code
  #   end
  #
  # @yieldparam error pass {#error} to a block
  # @yieldparam type pass {#type} to a block
  def catch
    yield(*to_ary)
  end

  alias or_else catch

  # Returns itself to the given block.
  # Use this to chain multiple service calls (since all services return Results).
  # It will short circuit your service call chain.
  #
  #
  # @example
  #   class UsersController < BaseController
  #     def create
  #       result = User::Create.(user_params) # if this fails the following calls won't run
  #                            .and_then { |user| User::SendWelcomeEmail.(user: user) }
  #                            .and_then { |user| User::Login.(user: user) }
  #
  #       if result.successful?
  #         json_success(result.value)
  #       else
  #         json_error(result.error)
  #       end
  #     end
  #   end
  #
  # @return [self]
  def and_then
    self
  end

  # See #and_then
  def then
    FService.deprecate!(name: "#{self.class}##{__method__}", alternative: '#and_then', from: caller[0])
    and_then
  end

  # Outputs a string representation of the object
  #
  #
  # @example
  #   puts FService::Result::Failure.new("Oh no!")
  #   # => Failure("Oh no!")
  #
  # @return [String] the object's string representation
  def to_s
    error.nil? ? 'Failure()' : "Failure(#{error.inspect})"
  end
end

Instance Method Details

#and_thenself

Returns itself to the given block. Use this to chain multiple service calls (since all services return Results). It will short circuit your service call chain.

Examples:

class UsersController < BaseController
  def create
    result = User::Create.(user_params) # if this fails the following calls won't run
                         .and_then { |user| User::SendWelcomeEmail.(user: user) }
                         .and_then { |user| User::Login.(user: user) }

    if result.successful?
      json_success(result.value)
    else
      json_error(result.error)
    end
  end
end

Returns:

  • (self)


109
110
111
# File 'lib/f_service/result/failure.rb', line 109

def and_then
  self
end

#catch {|error, type| ... } ⇒ Object Also known as: or_else

Returns the current error to the given block. Use this to chain multiple service calls (since all services return Results). It works just like the ‘.and_then` method, but only runs if the result is a Failure.

Examples:

class UpdateUserOnExternalService
  attribute :user_params

  def run
    check_api_status
      .and_then { update_user }
      .or_else { create_update_worker }
  end

  private
  # some code
end

Yield Parameters:



82
83
84
# File 'lib/f_service/result/failure.rb', line 82

def catch
  yield(*to_ary)
end

#failed?Boolean

Returns true.

Examples:

# Suppose that User::Update returns an FService::Result

log_errors(user) if User::Update.(user: user).failed?

Returns:

  • (Boolean)


46
47
48
# File 'lib/f_service/result/failure.rb', line 46

def failed?
  true
end

#successful?Boolean

Returns false.

Examples:

# Suppose that User::Update returns an FService::Result

log_errors(user) unless User::Update.(user: user).successful?

Returns:

  • (Boolean)


35
36
37
# File 'lib/f_service/result/failure.rb', line 35

def successful?
  false
end

#thenObject

See #and_then



114
115
116
117
# File 'lib/f_service/result/failure.rb', line 114

def then
  FService.deprecate!(name: "#{self.class}##{__method__}", alternative: '#and_then', from: caller[0])
  and_then
end

#to_sString

Outputs a string representation of the object

Examples:

puts FService::Result::Failure.new("Oh no!")
# => Failure("Oh no!")

Returns:

  • (String)

    the object’s string representation



127
128
129
# File 'lib/f_service/result/failure.rb', line 127

def to_s
  error.nil? ? 'Failure()' : "Failure(#{error.inspect})"
end

#valueObject

Failed operations do not have value.



51
52
53
# File 'lib/f_service/result/failure.rb', line 51

def value
  nil
end

#value!Object

Raises an exception if called. (see #value)

Raises:



57
58
59
# File 'lib/f_service/result/failure.rb', line 57

def value!
  raise Result::Error, 'Failure objects do not have value'
end