Is it ok to define private helper methods that use add_error?
OpenCoderX opened this issue · comments
Should we expect execute to halt if helper_method adds_error? Such as:
class ClientActivate < Mutations::Command
required do
string :location_uuid, matches: UUID_REGEX
end
def validate
@location = ClientLocation.find_by(uuid: location_uuid)
if !@location
add_error(:location_not_found, :not_found, "Location not found")
end
@user = User.find_by(uuid: user_uuid)
if !@user
add_error(:user_not_found, :not_found, "User not found")
end
end
def execute
begin
tx = start_transaction
@location.status = 1
@user.generate_timeline_event("Client Location Activation", "Activated Client Location: #{@location.uuid}")
@location.save
helper_method # helper method call here
@location
rescue StandardError => e
add_error(:client_location_activate, :final_save, "Client Location activate transaction failed: #{e}")
tx.failure
ensure
tx.close
end
end
private
def helper_method
add_error()
end
end
@cypriss are there any best practices around raising errors in helper methods?
I can't really tell what the question is here - could you explain what you expected to happen, what actually happened, and why you believe it's incorrect?
I'm trying to understand the bast practices around calling add_error in helper methods that are themselves called from the execute method. In the docs we recommend this when add_error is used directly in the execute method,
def execute
if password != password_confirmation
add_error(:password_confirmation, :doesnt_match, "Your passwords don't match")
return
end
end
if condition fails, we call add_error then explicit return but if you call add_error from a helper method the explicit return does not halt execution in the execute method.
I don't think anything is incorrect I just want to read some thoughts on how other users handle calling helper methods from the execute method, do you avoid using add_error in those helper methods if you want to halt execution of the calling execute method.
Should we not do this and instead inline code from helper methods or possible write the helper methods so they do not mutate but rather have the helper methods be more functional then have the execute method evaluate the result of the helper method and only call add_error from execute?
Apologies If I am not clear.
Thanks, I understand now.
I looked through our codebase, which has 897 calls to add_error
. The vast majority are inside validate
methods, which means they don't need an explicit return.
Most of the others called add_error
in a rescue
block inside execute
:
def execute
create_a_thing
rescue ActiveRecord::RecordNotUnique
add_error :thing, :not_unique, "Thing already exists"
end
Some also used the add_error(...); return
pattern recommended in the README.
I did find one example of using a helper method in the way you described:
def execute
helper_method
return if has_errors?
# ...
end
def helper_method
add_error(...)
end
I don't love this approach, since you have to remember to add the has_errors?
check.
We could potentially add support for something like throw :halt
to allow you to halt the command from inside a helper method but still return an Outcome
object to the caller.
@eugeneius your thoughts on this help tremendously, thank you. I'm going to review our codebase and try to standardize the ways in which we raise errors and possibly add some notes in the readme/wiki regarding these strategies.