Search code examples
ruby-on-railsrubyoctokit

Rails 6 how to handle 404 from Github file fetching using Octokit


In my Rails 6 app I'm trying to implement functionality which is responsible for fetching the file from a different Github repo. The code should try to fetch file name.json or name.master.json from GitHub (because the file could be either master json or standard json).

Code below:

#lib/github_client.rb

module GithubClient
  extend self

  def fetch_file(file_name)
    if (response = translate(file_name)).success?
      response
    else
      translate(file_name, master: true)
    end
  end
  
  private

  def client
    @client ||= Octokit::Client.new(access_token: Rails.application.credentials.github[:access_token])
  end

  def translate(file_name, master: false)
    return client.contents('user/my-repo-name', path: "#{file_name}.master.json") if master == 'true'

    client.contents('user/my-repo-name', path: "#{file_name}.json")
  end
end

Line if (response = translate(file_name)).success?does not work because if there is no file e.g. book.master.json it will return:

Octokit::NotFound (GET https://api.github.com/repos/user/my-repo-name/book.json: 404 - Not Found // See: https://docs.github.com/rest/reference/repos#get-repository-content)

How can I check the status of this response so that it will search for another file if necessary?


Solution

  • I'm not sure if there's an #exists? method or similar, which would probably be a better solution (I can't see such a method in the documentation!...), but you could always just rescue the exception in order to handle an expected failure gracefully. For example:

      client.contents('user/my-repo-name', path: "#{file_name}.json")
    rescue Octokit::NotFound
      client.contents('user/my-repo-name', path: "#{file_name}.master.json")
    

    Note that your current code is also slightly wrong since you're checking if master == 'true' -- but master is a boolean value (true / false), not a String ("true").

    true != "true"