Class: Uncaught::Client
- Inherits:
-
Object
- Object
- Uncaught::Client
- Defined in:
- lib/uncaught/client.rb
Overview
The main SDK client. Captures errors and sends them through the transport pipeline.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
-
#add_breadcrumb(type:, category:, message:, data: nil, level: nil) ⇒ Object
Add a breadcrumb to the ring buffer.
-
#capture_error(error, request: nil, operation: nil, component_stack: nil, level: "error") ⇒ String?
Capture an error and send it through the transport pipeline.
-
#capture_message(message, level: "info") ⇒ String?
Capture a plain message (not backed by an Exception instance).
-
#flush ⇒ Object
Flush all queued events to the transport.
-
#initialize(config) ⇒ Client
constructor
A new instance of Client.
-
#set_user(user) ⇒ Object
Set user context that will be attached to subsequent events.
Constructor Details
#initialize(config) ⇒ Client
Returns a new instance of Client.
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/uncaught/client.rb', line 15 def initialize(config) @config = config @breadcrumbs = BreadcrumbStore.new(config. || 20) @transport = Uncaught.create_transport(config) @rate_limiter = RateLimiter.new( global_max: config.max_events_per_minute || 30 ) @session_id = SecureRandom.uuid @seen_fingerprints = Set.new @user = nil @mutex = Mutex.new end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
12 13 14 |
# File 'lib/uncaught/client.rb', line 12 def config @config end |
Instance Method Details
#add_breadcrumb(type:, category:, message:, data: nil, level: nil) ⇒ Object
Add a breadcrumb to the ring buffer.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/uncaught/client.rb', line 142 def (type:, category:, message:, data: nil, level: nil) return unless @config.enabled @breadcrumbs.add( type: type, category: category, message: , data: data, level: level ) rescue => e debug_log("add_breadcrumb failed: #{e.}") end |
#capture_error(error, request: nil, operation: nil, component_stack: nil, level: "error") ⇒ String?
Capture an error and send it through the transport pipeline.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 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 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/uncaught/client.rb', line 36 def capture_error(error, request: nil, operation: nil, component_stack: nil, level: "error") return nil unless @config.enabled # --- Normalise error --- error_info = normalise_error(error) error_info.component_stack = component_stack if component_stack # --- Check ignoreErrors --- if should_ignore?(error_info.) debug_log("Event ignored by ignoreErrors filter") return nil end # --- Fingerprint --- fingerprint = Fingerprint.generate( type: error_info.type, message: error_info., stack: error_info.stack ) # --- Rate limit --- unless @rate_limiter.should_allow?(fingerprint) debug_log("Rate-limited: #{fingerprint}") return nil end # --- Collect breadcrumbs --- crumbs = @breadcrumbs.get_all # --- Detect environment --- environment = EnvDetector.detect # Attach deployment environment from config environment.deploy = @config.environment if @config.environment environment.framework = @config.framework if @config.framework environment.framework_version = @config.framework_version if @config.framework_version # --- Build event --- event_id = SecureRandom.uuid event = UncaughtEvent.new( event_id: event_id, timestamp: Time.now.utc.iso8601(3), project_key: @config.project_key, level: level, fingerprint: fingerprint, release: @config.release, error: error_info, breadcrumbs: crumbs, request: request, operation: operation, environment: environment, user: build_user_info, fix_prompt: "", sdk: SdkInfo.new(name: SDK_NAME, version: VERSION) ) # --- Sanitise --- event = Sanitizer.sanitize(event, @config.sanitize_keys) # --- Build fix prompt --- event.fix_prompt = PromptBuilder.build(event) # --- beforeSend hook --- if @config.before_send result = @config.before_send.call(event) if result.nil? debug_log("Event dropped by beforeSend") return nil end event = result end # --- Send --- @transport.send_event(event) debug_log("Captured event: #{event_id} (#{fingerprint})") # --- Track seen fingerprints --- @mutex.synchronize do @seen_fingerprints.add(fingerprint) end event_id rescue => e debug_log("capture_error failed: #{e.}") nil end |
#capture_message(message, level: "info") ⇒ String?
Capture a plain message (not backed by an Exception instance).
128 129 130 131 132 133 |
# File 'lib/uncaught/client.rb', line 128 def (, level: "info") capture_error(RuntimeError.new(), level: level) rescue => e debug_log("capture_message failed: #{e.}") nil end |
#flush ⇒ Object
Flush all queued events to the transport.
178 179 180 181 182 |
# File 'lib/uncaught/client.rb', line 178 def flush @transport.flush rescue => e debug_log("flush failed: #{e.}") end |
#set_user(user) ⇒ Object
Set user context that will be attached to subsequent events.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/uncaught/client.rb', line 159 def set_user(user) @mutex.synchronize do if user.nil? @user = nil elsif user.is_a?(UserInfo) @user = user.dup elsif user.is_a?(Hash) @user = UserInfo.new( id: user[:id] || user["id"], email: user[:email] || user["email"], username: user[:username] || user["username"] ) end end rescue => e debug_log("set_user failed: #{e.}") end |