Rails 6 adds ActiveSupport::ActionableError

Taha Husain

Taha Husain

October 1, 2019

This blog is part of our  Rails 6 series.

When working in a team on a Rails application, we often bump into PendingMigrationError or other errors that need us to run a rails command, rake task etc.

Rails introduced a way to resolve such frequent errors in development from error page itself.

Rails 6 added ActiveSupport::ActionableError module to define actions we want perform on errors, right from the error page.

For example, this is how PendingMigrationError page looks like in Rails 6.

How Actionable error looks like in Rails 6

By default, a button is added on error screen that says Run pending migrations. Clicking on this button would dispatch rails db:migrate action. Page will reload once migrations run successfully.

We can also define custom actions to execute on errors.

How to define actions on error?

We need to include ActiveSupport::ActionableError module in our error class. We can monkey patch an existing error class or define custom error class.

#action api is provided to define actions on error. First argument in #action is name of the action. This string would be displayed on the button on error page. Second argument is a block where we can write commands or code to fix the error.

Let's take an example of seeding posts data from controller, if posts not already present.


# app/controllers/posts_controller.rb

class PostsController < ApplicationController

def index
@posts = Post.all
if @posts.empty?
raise PostsMissingError
end
end

end

# app/errors/posts_missing_error.rb

class PostsMissingError < StandardError

include ActiveSupport::ActionableError

action "seed posts data" do
Rails::Command.invoke 'posts:seed'
end

end


# lib/tasks/posts.rake

namespace :posts do

desc 'posts seed task'
task :seed do
Post.create(title: 'First Post')
end

end

# app/views/posts/index.html.erb

<% @posts.each do |post| %>
<%= post.title %>
<% end %>

Let's check /posts (posts#index action) when no posts are present. We would get an error page with an action button on it as shown below.

Actionable error - seed posts data

Clicking on seed posts data action button will run our rake task and create posts. Rails will automatically reload /posts after running rake task.

Posts index page

ActionDispatch::ActionableExceptions middleware takes care of invoking actions from error page. ActionableExceptions middleware dispatches action to ActionableError and redirects back when action block has successfully run. Action buttons are added on error page from this middleware template.

Checkout the pull request for more information on actionable error.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.