adomokos / light-service

Series of Actions with an emphasis on simplicity.
MIT License
837 stars 67 forks source link

"ctx.fail!" should skip the rest of the code in the current action #112

Closed adomokos closed 7 years ago

adomokos commented 7 years ago

In the past week, I've observed two developers being confused with the use of ctx.fail!.

Consider this code:

class FindsUserAction
  extend LightService::Action

  expects :params
  promises :user

  executed do |ctx|
    ctx.fail!("user_id wasn't in the params") unless params.keys.include?('user_id')

    ctx.user = User.find(params[:user_id])
  end
end

They were surprised to see that the code after the ctx.fail! in this action got executed. Yes, as you need to explicitly return from the executed block by calling next:

class FindsUserAction
  extend LightService::Action

  expects :params
  promises :user

  executed do |ctx|
    if params.keys.include?('user_id') == false
      ctx.fail!("user_id wasn't in the params")
      next ctx
    end 

    ctx.user = User.find(params[:user_id])
  end
end

After seeing the engineers got tripped on this one, I am of the opinion, that the first example should behave as the developers expect it: when fail! is invoked, it should return from the execution context immediately without explicitly calling next ctx.