Rails 6 adds ActiveSupport::ActionableError

Taha Husain

By Taha Husain

on 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.

1
2# app/controllers/posts_controller.rb
3
4class PostsController < ApplicationController
5
6def index
7@posts = Post.all
8if @posts.empty?
9raise PostsMissingError
10end
11end
12
13end
1
2# app/errors/posts_missing_error.rb
3
4class PostsMissingError < StandardError
5
6include ActiveSupport::ActionableError
7
8action "seed posts data" do
9Rails::Command.invoke 'posts:seed'
10end
11
12end
13
1
2# lib/tasks/posts.rake
3
4namespace :posts do
5
6desc 'posts seed task'
7task :seed do
8Post.create(title: 'First Post')
9end
10
11end
1
2# app/views/posts/index.html.erb
3
4<% @posts.each do |post| %>
5<%= post.title %>
6<% 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.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.