DEV Community

MN Mark
MN Mark

Posted on

Failing First / Failing Fast

Failing First and Failing Fast

When writing new code I typically focus on the successful path first, and this seems to almost always result in terrible code. Terrible code on the first pass isn't really a problem, a brain dump into code usually produces bad code, at least for me. The important thing is that the brain dump code gets followed up on one or more times to simplify the logic. Too often those passes are months or even years later.

Example case is validating a Single-Sign-On (SSO) token in a cookie with Lua and Nginx.

My first pass included something like this:

code is simplified for illustration

function check_sso()
  local cookies = ngx.req.get_headers()['Cookie']
  if cookies then
    local token = cookies:match('sso_token=([^; ]+)')
    if token then
      local username = get_username_from_token(token)
      if username then
        if is_member_of(username, GROUP_NAME) then
          return true
        else
          ngx.log(ngx.WARN, username .. ' is not in group ' .. GROUP_NAME)
          return false
        end
      end
    end
  end
end

That follows a simple logic when you read through it, but it's hideous to look at and easy to lose your place in the nesting. The actual code with debug logging and token caching is worse due to the length of the nested blocks.

Consider what it looks like when we handle the failing side of the checks first:

function check_sso()
  local cookies = ngx.req.get_headers()['Cookie']
  if not cookies then
    return false
  end
  local token = cookies:match('sso_token=([^; ]+)')
  if not token then
    return false
  end
  local username = get_username_from_token(token)
  if not username then
    return false
  end
  if is_member_of(username, GROUP_NAME) then
    return true
  else
    ngx.log(ngx.WARN, username .. ' is not in group ' .. GROUP_NAME)
    return false
  end
end

Despite being more lines I find this version simpler and visually easier to read. When I come back to code written like this I find it much easier to modify and troubleshoot. Yet I still struggle to modify my thinking to use this type logic in the first place.

Anyone else have similar trouble with thought process differing from optimal code logic?

Does anyone disagree and think the first example is better or at least no worse than the second?

Discussion (0)