This blog is part of our Rails 6 series. Rails 6.0 was recently released.

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.

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.

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

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.