yegor256/0pdd

`JiraRepo#issue` returns wrong type and does not rescue `JIRA::HTTPError`

Open

#851 建立於 2026年5月11日

在 GitHub 查看
 (1 留言) (0 反應) (0 負責人)Ruby (37 fork)github user discovery
bughelp wanted

倉庫指標

Star
 (142 star)
PR 合併指標
 (PR 指標待抓取)

描述

What happens

In objects/vcs/jira.rb, JiraRepo#issue returns the raw JIRA::Resource::Issue object:

def issue(issue_id)
  @client.Issue.find(issue_id)
end

This breaks two contracts at once.

1. Return-type mismatch. GithubRepo#issue (objects/vcs/github.rb:38-46) and GitlabRepo#issue (objects/vcs/gitlab.rb:23-44) both return a { state:, author:, milestone: } hash. The Tickets#close consumer does:

return true if @vcs.issue(issue)[:state] == 'closed'

(objects/tickets/tickets.rb:39). Indexing a JIRA::Resource::Issue with [:state] does not return a state string — it goes through method_missing and yields something quite different from 'closed'. So the return true short-circuit never fires for JIRA, and close_issue is always called even on already-closed issues.

2. No rescue. @client.Issue.find(issue_id) raises on missing or inaccessible issues. The sibling JiraRepo#exists? (line 60-66) correctly rescues JIRA::NotFound, but issue does not — so a 404, 403, or transport error propagates unhandled to Tickets#notify and Tickets#close. Also note: Tickets#notify (tickets.rb:21) lists JIRA::NotFound in its rescue chain, but the jira-ruby gem actually raises JIRA::HTTPError for not-found — so the existing rescue likely never matched either.

What should happen

Make JiraRepo#issue match the contract that GithubRepo#issue and GitlabRepo#issue already implement, and rescue the actual jira-ruby exception class:

def issue(issue_id)
  issue = @client.Issue.find(issue_id)
  {
    state: issue.fields['status']['statusCategory']['key'] == 'done' ? 'closed' : 'open',
    author: issue.fields.dig('reporter', 'displayName'),
    milestone: nil
  }
rescue JIRA::HTTPError => e
  raise "Can't read JIRA issue #{issue_id}: #{e.message}"
end

(Adjust the state mapping to the JIRA workflow that 0pdd actually integrates with.) Result: the polymorphic contract used by Tickets#close is honoured, already-closed JIRA issues are detected, and missing JIRA issues surface as a single recognizable exception family. Add a corresponding rescue in Tickets#notify for JIRA::HTTPError.

貢獻者指南