Class: BugReportsClient::ApiClient

Inherits:
Object
  • Object
show all
Defined in:
app/services/bug_reports_client/api_client.rb

Overview

HTTP client for the central bug-reports API. Self-contained (no host dependencies): Bearer-token auth, JSON encoding, timeout retries, and Result objects so controllers can branch on success without rescuing.

Defined Under Namespace

Classes: ApiError, AuthenticationError, Result, ValidationError

Instance Method Summary collapse

Constructor Details

#initialize(config: BugReportsClient.config) ⇒ ApiClient

Returns a new instance of ApiClient.



18
19
20
21
# File 'app/services/bug_reports_client/api_client.rb', line 18

def initialize(config: BugReportsClient.config)
  @config = config
  raise AuthenticationError, "BUG_REPORT_API_KEY not configured" if @config.api_key.blank?
end

Instance Method Details

#create_bug_report(title:, description:, reporter_email:, severity: nil, report_type: "bug", reporter_name: nil, reporter_external: false) ⇒ Object

Submit a new report. The description carries all formatted details (answers, reporter, screenshots) as markdown for the GitHub issue. POST /api/bug_reports



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'app/services/bug_reports_client/api_client.rb', line 26

def create_bug_report(title:, description:, reporter_email:, severity: nil, report_type: "bug", reporter_name: nil, reporter_external: false)
  body = {
    bug_report: {
      title: prefixed_title(title, report_type),
      description: description,
      severity: severity,
      report_type: report_type,
      reporter_email: reporter_email,
      reporter_name: reporter_name,
      reporter_external: reporter_external,
      source: @config.source!,
      callback_url: @config.callback_url
    }
  }

  response = post("/bug_reports", body)
  Result.new(true, "Report submitted successfully", response)
rescue ValidationError => e
  Result.new(false, "Validation error: #{e.message}")
rescue => e
  # Full details go to the log only - raw exception text can leak
  # internal hosts/URLs into user-facing flash messages.
  Rails.logger.error "BugReportsClient: failed to create bug report: #{e.message}"
  Result.new(false, I18n.t("bug_reports_client.flashes.submit_failed"))
end

#create_error_report(title:, description:, fingerprint:, occurred_at:, severity: "high") ⇒ Object

Submit an automatic error report (500 capture). The API deduplicates by fingerprint - repeats of an open error bump its occurrence count. POST /api/error_reports



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/bug_reports_client/api_client.rb', line 55

def create_error_report(title:, description:, fingerprint:, occurred_at:, severity: "high")
  body = {
    error_report: {
      title: title,
      description: description,
      fingerprint: fingerprint,
      occurred_at: occurred_at,
      severity: severity,
      source: @config.source!
    }
  }

  response = post("/error_reports", body)
  Result.new(true, "Error report submitted", response)
rescue ValidationError => e
  Result.new(false, "Validation error: #{e.message}")
rescue => e
  Rails.logger.error "BugReportsClient: failed to create error report: #{e.message}"
  Result.new(false, I18n.t("bug_reports_client.flashes.submit_failed"))
end

#update_bug_report(id, title:, description:, severity: nil, report_type: "bug") ⇒ Object

Update an existing report on the API. PATCH /api/bug_reports/:id



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'app/services/bug_reports_client/api_client.rb', line 78

def update_bug_report(id, title:, description:, severity: nil, report_type: "bug")
  body = {
    bug_report: {
      title: prefixed_title(title, report_type),
      description: description,
      severity: severity,
      report_type: report_type
    }
  }

  response = patch("/bug_reports/#{id}", body)
  Result.new(true, "Report updated successfully", response)
rescue ValidationError => e
  Result.new(false, "Validation error: #{e.message}")
rescue => e
  Rails.logger.error "BugReportsClient: failed to update bug report #{id}: #{e.message}"
  Result.new(false, I18n.t("bug_reports_client.flashes.submit_failed"))
end