sumoheavy / jira-ruby

A Ruby gem for the JIRA REST API
MIT License
654 stars 411 forks source link

Getting "undefined method `presence` for "Not Found":String" error when issue is not found #432

Open tory-kk opened 5 months ago

tory-kk commented 5 months ago

Hello, I am getting the following error when the issue is not found:

/home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/http_error.rb:11:in `initialize': undefined method `presence' for "Not Found":String (NoMethodError)

      @message = response.try(:message).presence || response.try(:body)
                                       ^^^^^^^^^
Did you mean?  presence_in
        from /home/user/Projects/Ruby-test/announce/jira_client.rb:13:in `exception'
        from /home/user/Projects/Ruby-test/announce/jira_client.rb:13:in `raise'
        from /home/user/Projects/Ruby-test/announce/jira_client.rb:13:in `request'
        from /home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/client.rb:306:in `request'
        from /home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/client.rb:279:in `get'
        from /home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/resource/issue.rb:95:in `fetch'
        from /home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/base.rb:107:in `find'
        from /home/user/bundler/ruby/3.2.0/gems/jira-ruby-2.3.0/lib/jira/base_factory.rb:31:in `block (2 levels) in delegate_to_target_class'
        from /home/user/Projects/Ruby-test/announce/jira_client.rb:54:in `get_issue'

Jira-ruby version: 2.3.0. Enabled http_debug and added logs:

get: /rest/api/2/issue/ABC-123?fields=summary%2Cstatus%2Cissuetype - []
RESPONSE: #<Net::HTTPNotFound:0x00007f603b8f3ac0>

Please advise on how it could be fixed.

UPD: Jira JSON response:

{"errorMessages":["Issue does not exist or you do not have permission to see it."],"errors":{}}
purp commented 5 months ago

It's failing because Net:HTTP can't open the URL and get a response.

I got this error when the config options :site and :context_path options weren't set well. Getting those set correctly solved it for me.

dimas commented 5 months ago

Point of the report is that library should be prepared for this case probably and not crash with NoMethodError...

      @message = response.try(:message).try(:presence) || response.try(:body)

instead of

      @message = response.try(:message).presence || response.try(:body)

seem to do the trick...

tory-kk commented 5 months ago

RESPONSE: #

The response was successfully received and it was NotFound. The thing is that Jira returned HTTP status 404 and HTML page in the body (Content-Type text/html), so HTTPError construction failed.

UPD: Managed to get a JSON response, and it has the following format:

{"errorMessages":["Issue does not exist or you do not have permission to see it."],"errors":{}}

So the issue is not related to :site and :context_path configuration and can be triggered by trying to load non-existent ticket.

bobbrodie commented 5 months ago

@tory-kk when using the latest version from my master branch, I'm seeing the intended behavior. Version 3.0.0 should be released shortly (I'm talking to a teammate tomorrow to approve some of my PRs so I don't self-approve).

The most recent PR that touched on this specific issue is https://github.com/sumoheavy/jira-ruby/pull/435.

Note: Loading active_support/core_ext/object modifies to_json output, so I have a PR to address the tests for the referenced PR.

My Gemfile:

source 'https://rubygems.org'

gem 'jira-ruby', git: 'https://github.com/sumoheavy/jira-ruby', branch: 'master'

If you check out lib/jira/request_client.rb, you'll see how this is handled:

...
# Returns the response if the request was successful (HTTP::2xx) and
# raises a JIRA::HTTPError if it was not successful, with the response
# attached.

def request(*args)
  response = make_request(*args)
  raise HTTPError, response unless response.is_a?(Net::HTTPSuccess)
  response
end
...

And here's my response when requesting an issue that doesn't exist:

/Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/request_client.rb:13:in `request': Not Found (JIRA::HTTPError)
    from /Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/client.rb:306:in `request'
    from /Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/client.rb:279:in `get'
    from /Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/resource/issue.rb:95:in `fetch'
    from /Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/base.rb:107:in `find'
    from /Users/robert/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/bundler/gems/jira-ruby-2e6de8ebb573/lib/jira/base_factory.rb:31:in `block (2 levels) in delegate_to_target_class'
    from jira.rb:27:in `<main>'

When I request an issue that doesn't exist, I am receiving an HTTPError as expected. If you inspect the HTTPError with something like this:

begin
  client.Issue.find('NOEXIST-2')
rescue => e
  puts JSON.parse(e.response.body.inspect)
end

Then you'll see what you're looking for:

{"errorMessages":["Issue does not exist or you do not have permission to see it."],"errors":{}}

I think it will be OK to flag this as a duplicate for now, but wanted to run this by you before closing, since it should be working in the upcoming version :)

Thanks!

UPDATE 2024-04-27 I've come across multiple folks in the issues that have asked about HTTPError so I've enabled the wiki and added a page about it: https://github.com/sumoheavy/jira-ruby/wiki/Handling-HTTPError.

keegangroth commented 3 months ago

For anyone else who finds this before it's released, I was able to work around this by using the require from the previously linked #435 after I required this gem. Like so:

require 'jira-ruby'
require 'active_support/core_ext/object'