blog.waterlow.work

Ruby, Rails, js, etc...

Rails アンチパターン - 無視されるエラー(Inaudible Failures)

引き続きRails AntiPatternsという本を読んでいます。

https://www.amazon.co.jp/dp/B004C04QE0/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

前回は10 Building for Failureの1つめ「Continual Catastrophe」についてまとめました。

waterlow2013.hatenablog.com

今回は10 Building for Failureの2つめ「Inaudible Failures」についてまとめます。

Inaudible Failures

エラー対策はUXに影響を与える。

class Ticket < ApplicationRecord
  def self.bulk_change_owner(user)
    all.each do |ticket|
      ticket.owner = user
      ticket.save
    end
  end
end

たとえばこのようなコードでは、Ticketモデルのバリデーションでエラーになってしまってもスルーしてしまう。 ユーザにとって同じ結果でも削除されていたりされていなかったりする。

Solution: Never Fail Quietly

そんなことはやめようという話。

上のサンプルコードでれば、saveは保存できなかったときに例外をあげるsave!に変える。 またエラーが発生した場合にロールバックするためにトランザクションで囲む。そのほうが一貫性がある。

class Ticket < ApplicationRecord
  def self.bulk_change_owner(user)
    transaction do
      all.each do |ticket|
        ticket.owner = user
        ticket.save!
      end
    end
  end
end

その他以下のようなtipsがある。

  • controllerのrescue_fromで500用エラー画面を出す。
  • rescue nilは使わない。
  • 外部サービスを使ってエラーを蓄積・通知する。

まとめ

この章もその通りだなという感じでした。rescue_from使うとか、外部サービス使うとかは確実にやっていきたいです。
rescueについては前も書いたのですが、StandardErrorではなく限定された例外をrescueするのが良さそう。