初めに
過去にエラーの処理に関する記事を書きました
それがこれ
この記事を書いたところ
Railsのエラー処理については、たしかにrescue_fromを使うと様々なエラーを処理することができますが、個人的にはあまり多用すべきではないと思っています。
という話を聞き少し調べてみました。
rails guidesでは
rails guidesにはrescure_fromのところで
rescue_fromにExceptionやStandardErrorを指定すると、Railsでの正しい例外ハンドリングが阻害されて深刻な副作用が生じる可能性があります。よほどの理由がない限り、この指定はおすすめできません。
のように書いてあった。
アドバイスでは
もらったアドバイスでは
例外処理はかなり奥が深いですし、下手に実装するとかえって発生したエラーを迷宮入りさせてしまうことにもなりかねないので、原則は「エラーが起きても何もしない、フレームワークの共通処理に任せる」だと考えています。
という話だったのですが実際にアプリを作成する場合間違いなくエラーゼロなんていうのも難しいと思うので
ある程度のエラーハンドルは必要そう。
多用するのが良くないといってもどのくらいなら良いのかわからない…
そこでgitlabのソースコードを読んでみた。
rescue_fromで例外を補足してエラーページを出力しているコードがこちら
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
render "errors/encoding", layout: "errors", status: 500
end
rescue_from ActiveRecord::RecordNotFound do |exception|
log_exception(exception)
render_404
end
rescue_from(ActionController::UnknownFormat) do
render_404
end
rescue_from Gitlab::Access::AccessDeniedError do |exception|
render_403
end
rescue_from Gitlab::Auth::TooManyIps do |e|
head :forbidden, retry_after: Gitlab::Auth::UniqueIpsLimiter.config.unique_ips_limit_time_window
end
rescue_from GRPC::Unavailable, Gitlab::Git::CommandError do |exception|
log_exception(exception)
headers['Retry-After'] = exception.retry_after if exception.respond_to?(:retry_after)
render_503
end
上の三つは最初からrailsに搭載されているもので
エンコードのエラー,activerecord,actioncontrollerのエラーを取得している。
下の三つは独自のもので名前的に
権限関係と....よくわかんない(笑)
とりあえずgitlabで例外を補足していたのはテンプレートがなかった時レコードがなかった時エンコードの問題があったときだった。
エラーを補足した場合log_exceptionでログを出力していてそれがこのコード
def log_exception(exception)
Gitlab::Sentry.track_acceptable_exception(exception)
backtrace_cleaner = request.env["action_dispatch.backtrace_cleaner"]
application_trace = ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception).application_trace
application_trace.map! { |t| " #{t}\n" }
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
end
ActionDispatchとか知らんしなんで単純に
logger.error "#{exception.class.name} : #{exception.message}"
にしないのかよくわからん
まあとにかく
rescue_from exception
はしないようにします