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?
Top comments (0)