Module: Shipeasy::SDK::InternalReport

Defined in:
lib/shipeasy/sdk/internal_report.rb

Constant Summary collapse

INGEST_URL =

---- Baked-in destination ----

The main Shipeasy project (.shipeasy project_id e976b15e-3ccc-44d3-821d-87f06d5a0e43). The credential is a PUBLIC client key — the same class of credential already embedded verbatim in every browser bundle that ships the client SDK, and mirroring how the CLI bakes Shipeasy's own public key for setup-bug self-reporting — so baking it into the published gem is safe. /collect treats it as a write-only ingest key; it grants no read access. The canonical ingest host is api.shipeasy.ai (the SDK default base_url), which routes /collect to the edge worker.

"https://api.shipeasy.ai/collect".freeze
PLACEHOLDER_KEY =

Sentinel used until the real key is minted + baked. While INGEST_KEY is still the placeholder the channel stays fully inert (see .report), so a gem that ships before the key is provisioned never fires doomed requests. Mint the key with:

shipeasy keys create --type client --env prod \
--name "SDK internal error self-reporting" --scopes events:write

then replace the INGEST_KEY assignment below with the returned value.

"sdk_client_REPLACE_WITH_SHIPEASY_INTERNAL_ERROR_KEY".freeze
INGEST_KEY =

The baked-in ingest credential. Swap the placeholder for the real minted key here (this is the ONLY line to change when the key is provisioned).

"sdk_client_00bd4608a03e4084922978f9522614d5"
OUTCOME =

Stable consequence. The label (the safe_run operation name, e.g. "flags.get") is the subject; the outcome is fixed. Both are constant per operation — no variable data — so occurrences of the same internal bug fold into one issue on our dashboard (fingerprint = error_type + normalized message + top stack + subject|outcome). sdk marks which language SDK reported it.

"returned a safe default".freeze
SDK_ID =
"ruby".freeze

Class Method Summary collapse

Class Method Details

.key_configured?(key = @ingest_key || INGEST_KEY) ⇒ Boolean

True once a real key has been baked in (not the placeholder sentinel).

Returns:

  • (Boolean)


67
68
69
# File 'lib/shipeasy/sdk/internal_report.rb', line 67

def key_configured?(key = @ingest_key || INGEST_KEY)
  !key.nil? && !key.empty? && key != PLACEHOLDER_KEY
end

.report(label, err) ⇒ Object

Report an SDK-internal error to Shipeasy's own project. Called from Engine#safe_run's rescue. label is the swallowed operation (e.g. "flags.get") and becomes the stable issue subject. Never raises.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/shipeasy/sdk/internal_report.rb', line 85

def report(label, err)
  return unless @enabled
  key = @ingest_key || INGEST_KEY
  return unless key_configured?(key)

  ev = See.build_event(
    err,
    label.to_s,
    OUTCOME,
    { "sdk" => SDK_ID },
    sdk_version: @sdk_version || Shipeasy::SDK::VERSION,
    env: nil,
  )
  # Internal reports carry only the SDK-side context — never a consumer's
  # env or url — so a customer's config can't leak into our project.
  ev["side"] = @side || "server"

  limiter = (@limiter ||= See::Limiter.new)
  return unless limiter.should_send?(ev)

  send_event(key, JSON.generate({ events: [ev] }))
rescue StandardError
  # Self-reporting must never raise into product code.
  nil
end

.reset_for_test!Object

Reset module state (context + rate limiter + key override) so a spec starts from a clean, inert channel.



138
139
140
141
142
143
144
# File 'lib/shipeasy/sdk/internal_report.rb', line 138

def reset_for_test!
  @side        = nil
  @sdk_version = nil
  @enabled     = nil
  @limiter     = See::Limiter.new
  @ingest_key  = nil
end

.set_context(side:, sdk_version:, enabled: true) ⇒ Object

Wire the self-monitoring channel. Called from Engine#initialize with the bundle's side + version. enabled defaults on; it is forced off in test mode (no network) and when the caller opts out via disable_internal_error_reporting.



75
76
77
78
79
80
# File 'lib/shipeasy/sdk/internal_report.rb', line 75

def set_context(side:, sdk_version:, enabled: true)
  @side        = side
  @sdk_version = sdk_version
  @enabled     = enabled != false
  @limiter   ||= See::Limiter.new
end

.set_ingest_key_for_test(key) ⇒ Object

Stand in a real-looking key so specs can exercise the send path without the (deliberately inert) placeholder blocking it.



148
149
150
# File 'lib/shipeasy/sdk/internal_report.rb', line 148

def set_ingest_key_for_test(key)
  @ingest_key = key
end