-
Notifications
You must be signed in to change notification settings - Fork 13
Errors
stephenq edited this page Jun 30, 2025
·
3 revisions
Every op must implement a perform method. This is the method which will be executed if all validations pass.
When the the perform method is complete, the Op determines success based on whether errors is empty.
class MyFailingOp < ::Subroutine::Op
string :first_name
validates :first_name, presence: true
protected
def perform
errors.add(:base, "This Op will never succeed")
# but this line will execute
end
endNotice we do not declare perform as a public method. This is to ensure the "public" api of the op remains as submit or submit!.
You are able to fail fast within validations or perform if you invoke fail!. fail! can be invoked with no arguments or you can provide a field and message like errors.add.
class MyOp
string :first_name
protected
def perform
fail! :base, "What is going on, why would you do this?" if first_name == "Bob"
fail! :first_name, "is invalid" if first_name == "Ralph"
if first_name == "Douglas"
errors.add(:first_name, "cannot be Douglas")
fail!
end
end
endYou can also inherit errors from other objects that respond to errors in the same way:
class MyOp
integer :user_id
string :first_name
protected
def perform
user = ::User.find(user_id)
unless user.update(first_name: first_name)
inherit_errors(user)
end
# this line will still run because no `fail!` occurred and/or save! was not used
end
endErrors will be extracted from things like ActiveRecord objects if the resulting error is compatible:
class MyOp
integer :user_id
string :first_name
protected
def perform
user = ::User.find(user_id)
user.first_name = first_name
user.save!
# this line will not run if user is invalid
end
end