エラー処理の方法論

以前自分で実装していたときにいろいろやっていたので、まとめておく。

module Hoge
  class HogeError < StandardError
  end

  def self.raise_with_inherit
    some_process "hack"
  rescue ArgumentError => e
    error = HogeError.new e.message
    error.set_backtrace e.backtrace
    raise error
  end

  def self.raise_given
    some_process "some"
  rescue ArgumentError => e
    raise e
  end

  def self.some_process(label)
    occur label.upcase
  end

  def self.occur(*args)
    raise ArgumentError, args.to_s
  end
end

# Hoge.raise_with_inherit
# Hoge.raise_given
# Hoge.some_process "just"

# uncomment on execute

自前のエラーで吐き出す際には、backtraceをsetしてあげる。そうするとお行儀がいい感じに見える。

例えば、HTTPソケットのラッパーのメソッドをつくって、そのメソッドの利用者はエラーハンドリングを頑張らなくてよくする、みたいなときに使える。

Hoge.raise_with_inherit
#=>
# hoge.rb:24:in `occur': HACK (Hoge::HogeError)
#         from hoge.rb:20:in `some_process'
#         from hoge.rb:6:in `raise_with_inherit'
#         from hoge.rb:28
# 

受け流すだけでいいときは、特に工夫しない。

Hoge.raise_given
#=>
# hoge.rb:24:in `occur': SOME (ArgumentError)
#         from hoge.rb:20:in `some_process'
#         from hoge.rb:14:in `raise_given'
#         from hoge.rb:29
# 

いちおう、通常のraiseは以下のような挙動。

Hoge.some_process "just"
#=>
# hoge.rb:24:in `occur': JUST (ArgumentError)
#         from hoge.rb:20:in `some_process'
#         from hoge.rb:30
#