Why is the passed block being evaluated even when an exception is raised?

I have this function and the exception is being raised as expected. However, the block is still being evaluated even though the conditional returns false. What is happening here?

  def authorize_role!(from, to, required_role, do: block) when required_role in @roles do
    actual_role = role_for_schema!(from, to)

    if role_index(actual_role) >= role_index(required_role) do
      block
    else
      raise AuthorizationError
    end
  end

It needs to be a macro, not a function. block is being evaluated as soon as you pass it as a parameter at the callsite.

Yeah to expand on what @sodapopcan if you want to delay the execution of some code without a macro you’d use a function eg:

authorize_role!(from, to, required_role, fn ->
  # stuff that requires the role
end)

If you want to use a do block style then yeah that has to be a macro because you’re essentially re-arranging the AST to wrap the code in the if.

3 Likes

Oh ya, that is even better IMO.

1 Like

Thanks! I think a macro is overkill for this usecase, so passing in the callback makes sense. Thanks