Rails 6から導入されたActiveSupport::ActionableError
を使うと例外発生時に画面から任意の処理が実行できて便利そうだったので使い方とかをメモ📝
Rails標準ではActiveRecord::PendingMigrationErrorが発生時にこちらを使ってmigrationが行えるようになってますね!
この機能は通常のRails例外ページにボタンを追加し、ブラウザのエラーページでマイグレーションを実行してActiveRecord::PendingMigrationErrorエラーを解決できるようにします。 Rails 6のB面に隠れている地味にうれしい機能たち(翻訳)|TechRacho by BPS株式会社
ActiveSupport::ActionableErrorの使い方
使い方は簡単で、ActiveSupport::ActionableError
を
class MyException < StandardError include ActiveSupport::ActionableError action 'Oops!!' do puts 'Oops!! raised MyException!!' end end class PostsController < ApplicationController def new raise MyException end end
表示されているOops!!をクリックすると以下のようにログにaction
に定義したputs 'Oops!! raised MyException!!'
が実行されて結果が出力されています。
Oops!! raised MyException!!
任意を例外をActionableにする
以下のようなmoduleを使ってinitializerとかでrequireをすると既存の任意のエラーをActionableError
にすることができると思います。
require 'active_support/all' module EnableActionableError extend ActiveSupport::Concern included do include ActiveSupport::ActionableError action 'Oops!!' do puts 'your any process.' end end end TargetError.include(EnableActionableError)
(出来なかった)webpackのbuildがされてなかったらボタンクリックでbuildできるようにしたい
個人のサービスではsimpackerを使っているのでyarn buildが行われていなかった時にしたくて以下のようなファイルを作ってrequireはしてみたのですが、上手くいかなかった・・・😭
# frozen_string_literal: true require 'simpacker/manifest' require 'active_support/all' require 'action_view/template/error' module Patches module Simpacker module EnableActionableError extend ActiveSupport::Concern included do include ActiveSupport::ActionableError action 'Run yarn build for development' do system 'yarn build:dev' end end end end end # MEMO # Simpacker::Manifest::MissingEntryErrorがControllerで直接発生する場合にはいい感じに動作するが、 # `<%= javascript_pack_tag 'boards/new' %>`のような形でerb内で発生した場合には、 # `ActionView::Template::Error`になってしまうのでPatchが効かない。 # `ActionView::Template::Error`に直接includeしてもなぜか動かないが、 # そもそも`ActionView::Template::Error`にactionを設定するのは微妙な気がする。。。 Simpacker::Manifest::MissingEntryError.include(Patches::Simpacker::EnableActionableError) Simpacker::Manifest::MissingFileError.include(Patches::Simpacker::EnableActionableError) # ActionView::Template::Error.include(Patches::Simpacker::EnableActionableError)
Rails、template内で例外が発生すると、メッセージとかは実際の例外のものになるが実態はActionView::Template::Error
がraiseされているのと、ActionView::Template::Error
に直接includeしてもなぜか動かない。。。(そもそもActionView::Template::Error
にactionを設定するのは微妙な気がする。。。
The Template::Error exception is raised when the compilation or rendering of the template fails. This exception then gathers a bunch of intimate details and uses it to report a precise exception message.
rails/error.rb at 18707ab17fa492eb25ad2e8f9818a320dc20b823 · rails/rails · GitHub
おわりに
ActiveSupport::ActionableError
、手軽に使えるのと、色々出来て便利そうですね!