Class: RailsErrorDashboard::Commands::LinkExistingIssue

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_error_dashboard/commands/link_existing_issue.rb

Overview

Command: Link an existing issue URL to an error record

Parses the URL to extract provider, owner/repo, and issue number. No API call needed — just stores the relationship.

Examples:

result = LinkExistingIssue.call(error_id, issue_url: "https://github.com/user/repo/issues/42")
result[:success] # => true

Constant Summary collapse

PROVIDER_PATTERNS =
{
  github: %r{github\.com/([^/]+/[^/]+)/issues/(\d+)}i,
  gitlab: %r{gitlab\.com/([^/]+/[^/]+)/-/issues/(\d+)}i,
  codeberg: %r{codeberg\.org/([^/]+/[^/]+)/issues/(\d+)}i,
  # https://linear.app/<workspace>/issue/ENG-123/<slug> — capture team key + number
  linear: %r{linear\.app/[^/]+/issue/([A-Za-z][A-Za-z0-9]*)-(\d+)}i
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(error_id, issue_url:) ⇒ LinkExistingIssue

Returns a new instance of LinkExistingIssue.



26
27
28
29
# File 'lib/rails_error_dashboard/commands/link_existing_issue.rb', line 26

def initialize(error_id, issue_url:)
  @error_id = error_id
  @issue_url = issue_url.to_s.strip
end

Class Method Details

.call(error_id, issue_url:) ⇒ Object



22
23
24
# File 'lib/rails_error_dashboard/commands/link_existing_issue.rb', line 22

def self.call(error_id, issue_url:)
  new(error_id, issue_url: issue_url).call
end

Instance Method Details

#callObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rails_error_dashboard/commands/link_existing_issue.rb', line 31

def call
  return { success: false, error: "Issue URL is required" } if @issue_url.blank?

  error = ErrorLog.find(@error_id)
  parsed = parse_issue_url(@issue_url)

  error.update!(
    external_issue_url: @issue_url,
    external_issue_number: parsed[:number],
    external_issue_provider: parsed[:provider]&.to_s
  )

  { success: true, issue_url: @issue_url, provider: parsed[:provider] }
rescue ActiveRecord::RecordNotFound
  { success: false, error: "Error not found: #{@error_id}" }
rescue => e
  { success: false, error: "#{e.class}: #{e.message}" }
end