Battling HTML’s Lack of Error Messages
One of the very first things I learned about coding is that every character matters. Accidentally added an extra comma? Boo, your entire page crashes! Didn’t add a comma where you needed one? That query you were trying to execute isn’t even going to let you run it without yelling at you. Some languages and tools are pretty good at giving you errors so you can correct your mistakes, like Ruby and MySQL Workbench (despite its other flaws). One language that is notoriously bad at giving useful errors, or any error at all, is HTML — especially in the browser.
For this quarter’s hackathon, I decided to look back at my final project from coding bootcamp. It’s highly simplistic and it looks like a newbie wrote it, but I’m still proud of it for only having been coding for a couple of months at that point. Take this monstrosity of a controller method to render different list objects based on the difficulty attribute they were assigned:
def difficulty_index
if list.find(params[:id]) == "/fiveoutoffive"
lists = List.all
elsif list.find(params[:id]) == "/fouroutoffive"
lists = List.all - List.where(difficulty: 5)
elsif list.find(params[:id]) == "/threeoutoffive"
lists = List.all - List.where(difficulty: 5) && List.where(difficulty: 4)
elsif list.find(params[:id]) == "/twooutoffive"
lists = List.where(difficulty: 1) && List.where(difficulty: 2)
else
lists = List.where(difficulty: 1)
end render locals: {
lists: lists
}
end

Aside from cringing at how flippantly un-DRY my code was, I also noticed that my list objects weren’t saying. Using my newfound debugging skills, I got to work employing every new tactic I had learned in the past year to figure out why this feature wasn’t working. I’ll walk you quickly through my process.
- Open up the server logs to see if there was an error or a rollback. The only thing that happened was the form rendered. No luck there.
- Go to console to see if I can add a new list object from there — this would tell me if there was a problem with the controller methods or if my model was written incorrectly. I inserted a new list object just fine and saw it show up in the browser as soon as I refreshed the page. My validations were even working perfectly, as you can see in my first attempt to only insert a title while I required three other fields as well. While good for my database, this was bad for debugging purposes.
- Compare the code for each form between the list object, which was not working, and the task object, which oddly enough, was working. The forms looked the same, and at this point I hyper focused on the button that wasn’t responding when clicked.
- Inspected the page in the browser and went to the network tab to see if there was any activity that I wasn’t seeing in my server logs. It stayed blank. After clicking the button about a dozen times out of desperation, I finally asked for help.
It took me, my favorite senior developer, and about 20 minutes of retracing back through my steps, but we finally spotted the problem. Below is the partial to create a new list, and the problem file.
<div class='list-form'>
<div class="row">
<div class="col s10 offset-s1">
<h4 class='title'>
<%= form_title %>
</h4><% if list.errors.any? %>
<% list.errors.full_messages.each do |msg| %>
<p> <%= msg %></p>
<% end %>
<% end %><%= form_for(list, url: {action: 'create'}) do |f| %><span class="textarea1"></span>
<label for="title"></label>
<%= f.text_field :title, placeholder: 'Title Your List', class: 'form-control' %><label for="list_difficulty">Difficulty Level </label>
<a class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="On a scale from 1-5, how hard is this list going to be to complete?">?</a>
<form action="#">
<%= f.range_field(:difficulty, in: 1..5, class: 'range-field') %>
</form><label for="list_energy">Energy Level </label>
<a class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="On a scale from 1-5, how much energy is this list going to take?">?</a>
<%= f.range_field(:energy, in: 1..5, class: 'form-control') %><label for="due_date">Due Date </label>
<a class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="If you need to get this list done by a certain date, we'll text you a reminder that morning.">?</a>
<%= f.date_field :due_date %><label for="reward">Reward </label>
<a class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="You have the option to set a reward to motivate yourself.">?</a>
<%= f.text_field :reward, placeholder: 'Treat yoself', class: 'form-control' %><div><%= f.check_box(:public, {}, true, false) %>
<label for="list_public">Make This List Public? </label></div><p><div class ='new-list-btn'>
<%= f.submit class: 'btn' %>
</div>
<% end %>
</div>
</div>
</div>
See that little </form> tag that’s hanging out between the difficulty and energy fields? That caused the browser to only recognize Title and Difficulty Level as part of the form. Everything else, including the Submit button, was hanging out in la la land without any functionality — kind of like my parents’ nice silverware that only got any use because I insisted on breaking it out every Thanksgiving.
I don’t do it nearly often enough, but reading through my old code turned out to be a good learning experience as well as a bit of an ego boost. Not only did I get to see how much I’ve improved, but I almost stumped someone who’s been doing this for a lot longer than I have. That’s worth all the cringing I’ve been doing today.

