u16suzuの blog

日々学んだことのメモブログです。

Bundlerのエラー設計のメモ

  • Bundlerのエラー設計メモ
module Bundler
  class BundlerError < StandardError
    def self.status_code(code)
      define_method(:status_code) { code }

      if match = BundlerError.all_errors.find {|_k, v| v == code }
        error, _ = match
        raise ArgumentError,
          "Trying to register #{self} for status code #{code} but #{error} is already registered"
      end

      # 全てのエラーcodeリストを BundlerError に保持している. 上の部分で、同じ error code を登録しないためにそうしている。
      BundlerError.all_errors[self] = code
    end

    def self.all_errors
      @all_errors ||= {}
    end
  end

  class GemfileError < BundlerError; status_code(4); end
  class InstallError < BundlerError; status_code(5); end
  # message定義するケース
  class NoSpaceOnDeviceError < PermissionError
    def message
      "There was an error while trying to #{action} `#{@path}`. " \
      "There was insufficient space remaining on the device."
    end

    status_code(31)
  end
end
  • 例外をraiseするところ
raise BundlerError, "Unknown user path requested: #{dir}"
  • 例外ハンドリング周り
rescue GemfileNotFound
  bundle_dir = default_bundle_dir
  raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir
  Pathname.new(File.expand_path("..", bundle_dir))
end