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