Module: Shipeasy::SDK::See
- Defined in:
- lib/shipeasy/sdk/see.rb
Defined Under Namespace
Modules: Context Classes: Built, Chain, ControlFlowChain, ControlFlowTail, Limiter, NullChain, Violation
Constant Summary collapse
- SEE_MAX_MESSAGE =
---- Limits (mirror core.ts; kept in sync with the worker's /collect) ----
500- SEE_MAX_STACK =
8000- SEE_MAX_SUBJECT =
used for subject, outcome, error_type
200- SEE_MAX_EXTRA_VALUE =
200- SEE_MAX_EXTRA_KEYS =
20- SEE_DEDUP_WINDOW_MS =
30_000- SEE_MAX_PER_PROCESS =
25- DEFAULT_SUBJECT =
Default consequence parts when a chain omits them.
"app".freeze
- DEFAULT_OUTCOME =
"hit an error".freeze
- EXPECTED_IVAR =
Marker attribute stamped onto an exception by control_flow_exception().
:@__shipeasy_see_expected
Class Method Summary collapse
-
.build_event(problem, subject, outcome, extras, sdk_version:, env:) ⇒ Object
Build the type:"error" event accepted by POST /collect.
- .expected?(err) ⇒ Boolean
-
.mark_expected(err, because, extras = nil) ⇒ Object
Best-effort stamp marking an exception as expected control flow.
-
.sanitize_extras(extras) ⇒ Object
Drop nil values, keep only String/Numeric(finite)/boolean, truncate string values to 200 chars, cap at 20 keys (insertion order).
- .top_stack_line(stack) ⇒ Object
- .truncate(str, limit) ⇒ Object
Class Method Details
.build_event(problem, subject, outcome, extras, sdk_version:, env:) ⇒ Object
Build the type:"error" event accepted by POST /collect.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/shipeasy/sdk/see.rb', line 124 def build_event(problem, subject, outcome, extras, sdk_version:, env:) stack = nil if problem.is_a?(Violation) error_type = problem.name = problem.name kind = "violation" elsif problem.is_a?(Exception) error_type = problem.class.name || "Error" = (problem..to_s.empty? ? error_type : problem.) bt = problem.backtrace stack = bt.join("\n") if bt && !bt.empty? kind = "caught" else error_type = "Error" = problem.to_s kind = "caught" end ev = { "type" => "error", "kind" => kind, "error_type" => truncate(error_type, SEE_MAX_SUBJECT), "message" => truncate(, SEE_MAX_MESSAGE), "subject" => truncate(subject, SEE_MAX_SUBJECT), "outcome" => truncate(outcome, SEE_MAX_SUBJECT), "side" => "server", "sdk_version" => sdk_version, "ts" => (Time.now.to_f * 1000).to_i, } ev["stack"] = truncate(stack, SEE_MAX_STACK) if stack clean = sanitize_extras(extras) ev["extras"] = clean if clean ev["env"] = env if env && !env.to_s.empty? ev end |
.expected?(err) ⇒ Boolean
104 105 106 107 108 109 |
# File 'lib/shipeasy/sdk/see.rb', line 104 def expected?(err) err.instance_variable_defined?(EXPECTED_IVAR) && !err.instance_variable_get(EXPECTED_IVAR).nil? rescue StandardError false end |
.mark_expected(err, because, extras = nil) ⇒ Object
Best-effort stamp marking an exception as expected control flow.
94 95 96 97 98 99 100 101 102 |
# File 'lib/shipeasy/sdk/see.rb', line 94 def mark_expected(err, because, extras = nil) mark = { "because" => because.to_s } clean = sanitize_extras(extras) mark["extras"] = clean if clean err.instance_variable_set(EXPECTED_IVAR, mark) rescue StandardError # Frozen / builtin objects that reject ivars: best effort only. nil end |
.sanitize_extras(extras) ⇒ Object
Drop nil values, keep only String/Numeric(finite)/boolean, truncate string values to 200 chars, cap at 20 keys (insertion order). Returns nil if nothing is kept. Keys are stringified.
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 |
# File 'lib/shipeasy/sdk/see.rb', line 67 def sanitize_extras(extras) return nil unless extras.is_a?(Hash) return nil if extras.empty? out = {} extras.each do |k, v| break if out.size >= SEE_MAX_EXTRA_KEYS next if v.nil? case v when true, false out[k.to_s] = v when String out[k.to_s] = truncate(v, SEE_MAX_EXTRA_VALUE) when Numeric # Reject NaN / Infinity (not representable in JSON). next if v.respond_to?(:finite?) && !v.finite? out[k.to_s] = v else next end end out.empty? ? nil : out end |
.top_stack_line(stack) ⇒ Object
196 197 198 199 200 201 202 203 204 |
# File 'lib/shipeasy/sdk/see.rb', line 196 def top_stack_line(stack) return "" if stack.nil? || stack.empty? stack.each_line do |line| s = line.strip return s[0, 200] if s.start_with?("File ") || s.start_with?("at ") || s.include?("line ") || s.include?(":in ") end "" end |
.truncate(str, limit) ⇒ Object
59 60 61 62 |
# File 'lib/shipeasy/sdk/see.rb', line 59 def truncate(str, limit) s = str.to_s s.length <= limit ? s : s[0, limit] end |