Better Error Reporting of Liquid Exceptions in Jekyll
By Will Brady
Aug 15, 2012
The Problem
We recently converted our website to Jekyll. Along the way I occasionally ran into a very annoying problem. What would happen is (being new to Jekyll and Liquid) I would occasionally misspell a Liquid tag and not be notified by Jekyll during the build process. So for example let's say instead of the correct include tag
{% include sharing.html %}
I accidently write it as
{% inclde sharing.html %}
When I build the site using the jekyll command, Jekyll will let me know that my site compiled successfully
> jekyll
Configuration from /blog/_config.yml
Building site: /blog -> /blog/_site
Successfully generated site: /blog -> /blog/_site
Why are you lying to me Jekyll? There's no way it could have successfully interpreted "inclde". It didn't. Liquid gives a nice error message "Liquid syntax error: Unknown tag 'inclde'". Unfortunately Jekyll takes the liberty of going ahead and dropping that error message in your rendered page and not letting you know about it. You get something like this:

The Solution
The solution is to call .render! rather than simply .render on the Liquid templates in Jekyll. Liquid doesn't say much about the .render! method in its documentation, but its obvious when you look at its code. The .render! method does the same thing as the .render method except it actually raises an error rather than simply returning the error message. This is necessary for Jekyll who blindly passes the string results along. Jekyll's Convertible class already has the begin/rescue in place to catch the errors, its just not telling Liquid to throw them.
Simply changing the two lines which call .render on Liquid templates to .render! will solve the problem. In addition I added a backtrace dump and an abort of the build. This way Jekyll will no longer mislead you about its success.
begin
self.output = Liquid::Template.parse(layout.content).render!(payload, info)
rescue => e
puts "Liquid Exception: #{e.message} in #{self.data["layout"]}"
e.backtrace.each do |backtrace|
puts backtrace
end
abort("Build Failed")
end
I've created a gist of a monkey patch file to drop in your project's _plugins/ directory for a quick fix to this problem. This will overwrite the do_layout method only (not the entire Convertible module). I've also submitted a pull request to Jekyll.