error_radar 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 017c3eb241a062270368e74bf4a38e52caaf303ddfdc1848c3e1f88d0ea8219a
4
- data.tar.gz: '08d6b0982d7cfae71bdde4c466948b0091e1c000091030a8c6c5507139c32136'
3
+ metadata.gz: 2914a57eb370a3b003c69d8ab3e9899826dade79b35f62bffc97e8fed40748bf
4
+ data.tar.gz: f0f0772a121489558626b8780c1d10f3d1d08fb1e71b067c0a422c5da5eab709
5
5
  SHA512:
6
- metadata.gz: 887a6d150b9e3bbcade9f208f80b0ef89755b229716cf1d2798bd72fb1feb4b13a8feb480178fda95bf36e9b291426895066e5043ea22a48ac830f86887d8de6
7
- data.tar.gz: 67e779feaef2bafc575a3aa6b52c1d8af20e907d22edc1b4e769a5cab6a88969984503b74c9a1f6df70b51367d98ed5d7cb254b2ea405741bef4c09600057179
6
+ metadata.gz: e9ddda42dc56d8512da27db0fa371639b08925af149200fd4a016904eb2fdc2ee8fc7d4febb5b008db2b1f3e3b689acda1c068c1883d55f38fa833201346cb12
7
+ data.tar.gz: e76130935b55369dbb16d839a3d4e29fbe6c2cb28390915ffc43cee00bd8bb9c5ebc1585cecbbd656cfaf2a22d91465eb41e8529ee17ba91fae86023cf89563d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.2.0] - 2026-07-02
6
+
7
+ ### Added
8
+ - Host-configurable error categories. The `category` enum is no longer fixed:
9
+ register app-specific categories with `config.register_category(:name, int)`
10
+ or replace the map with `config.categories = {...}` (built-in defaults are
11
+ merged in first). Stored integers are treated as a schema and must stay
12
+ stable once data exists.
13
+
14
+ ### Notes
15
+ - Backward compatible: with no configuration the six built-in categories
16
+ (`application`, `external_api`, `background_job`, `syntax`, `database`,
17
+ `network`) behave exactly as in 0.1.0.
18
+
5
19
  ## [0.1.0] - 2026-06-18
6
20
 
7
21
  ### Added
data/README.md CHANGED
@@ -65,6 +65,26 @@ ErrorRadar.configure do |config|
65
65
  end
66
66
  ```
67
67
 
68
+ ### Custom categories
69
+
70
+ The `category` enum ships with six built-ins — `application`, `external_api`,
71
+ `background_job`, `syntax`, `database`, `network` — but is **not fixed**. Register
72
+ your own without touching the gem:
73
+
74
+ ```ruby
75
+ ErrorRadar.configure do |config|
76
+ config.register_category(:instagram_api, 6) # add one
77
+ # or replace the whole map (defaults are merged in first):
78
+ config.categories = { instagram_api: 6, payments_api: 7 }
79
+ end
80
+ ```
81
+
82
+ The integer is the value stored in the `category` column, so treat it as a
83
+ schema: keep it stable once you have data, and don't reuse a number for two
84
+ names (a collision raises at boot). Custom categories work everywhere a built-in
85
+ does — `capture`/`notify` calls, the `categorize` rules, the dashboard charts
86
+ and the RailsAdmin board.
87
+
68
88
  ## Use
69
89
 
70
90
  ```ruby
@@ -6,14 +6,11 @@ module ErrorRadar
6
6
  # One row per distinct failure (collapsed by fingerprint). Doubles as a task
7
7
  # on the triage board. Table: error_radar_error_logs.
8
8
  class ErrorLog < ApplicationRecord
9
- enum category: {
10
- application: 0, # generic Ruby/Rails runtime error
11
- external_api: 1, # any 3rd-party API error
12
- background_job: 2, # uncategorised background-job failure
13
- syntax: 3, # SyntaxError / NameError / NoMethodError / ArgumentError / TypeError
14
- database: 4, # ActiveRecord / DB level
15
- network: 5 # timeouts, connection resets, DNS, ...
16
- }, _prefix: :category
9
+ # Category map is host-configurable (built-in defaults + anything the app
10
+ # registers via ErrorRadar.config). Read at class-load, which happens after
11
+ # the host's initializer has run `ErrorRadar.configure`, so custom
12
+ # categories are already merged in. See ErrorRadar::Configuration.
13
+ enum category: ErrorRadar.config.categories, _prefix: :category
17
14
 
18
15
  enum severity: { info: 0, warning: 1, error: 2, critical: 3 }, _prefix: :severity
19
16
 
@@ -4,6 +4,17 @@ module ErrorRadar
4
4
  # Holds every host-app-specific decision so the engine stays decoupled.
5
5
  # Configure from an initializer (see the install generator's template).
6
6
  class Configuration
7
+ # Built-in categories (name => stored integer). Hosts can override the whole
8
+ # map (`config.categories = {...}`) or add their own (`register_category`).
9
+ DEFAULT_CATEGORIES = {
10
+ application: 0, # generic Ruby/Rails runtime error
11
+ external_api: 1, # any 3rd-party API error
12
+ background_job: 2, # uncategorised background-job failure
13
+ syntax: 3, # SyntaxError / NameError / NoMethodError / ArgumentError / TypeError
14
+ database: 4, # ActiveRecord / DB level
15
+ network: 5 # timeouts, connection resets, DNS, ...
16
+ }.freeze
17
+
7
18
  # Master switch — set false (e.g. in test env) to make capture a no-op.
8
19
  attr_accessor :enabled
9
20
 
@@ -43,6 +54,11 @@ module ErrorRadar
43
54
  # `->(controller) { "who@acted" }` — stamped onto resolved errors.
44
55
  attr_accessor :current_user
45
56
 
57
+ # The category name => integer map backing ErrorLog's `category` enum.
58
+ # Read-only accessor; mutate through `categories=` or `register_category`
59
+ # so the built-in defaults are always preserved.
60
+ attr_reader :categories
61
+
46
62
  def initialize
47
63
  @enabled = true
48
64
  @backtrace_lines = 30
@@ -65,6 +81,32 @@ module ErrorRadar
65
81
  @expected_servers = []
66
82
  @authenticate = nil
67
83
  @current_user = nil
84
+ @categories = DEFAULT_CATEGORIES.dup
85
+ end
86
+
87
+ # Replace the category map. The built-in defaults are merged in first, so a
88
+ # host only needs to list what it adds or renumbers:
89
+ # config.categories = { instagram_api: 6, background_job: 7 }
90
+ # Stored integers must stay stable once data exists — treat them as a schema.
91
+ def categories=(hash)
92
+ merged = DEFAULT_CATEGORIES.merge(hash.transform_keys(&:to_sym))
93
+ assert_unique_values!(merged)
94
+ @categories = merged
95
+ end
96
+
97
+ # Add a single custom category without disturbing the rest:
98
+ # config.register_category(:instagram_api, 6)
99
+ def register_category(name, value)
100
+ name = name.to_sym
101
+ value = Integer(value)
102
+ if @categories[name] && @categories[name] != value
103
+ raise ArgumentError, "category #{name.inspect} already mapped to #{@categories[name]}"
104
+ end
105
+ existing = @categories.key(value)
106
+ if existing && existing != name
107
+ raise ArgumentError, "category value #{value} already used by #{existing.inspect}"
108
+ end
109
+ @categories = @categories.merge(name => value)
68
110
  end
69
111
 
70
112
  # Convenience DSL inside `configure`:
@@ -77,5 +119,14 @@ module ErrorRadar
77
119
  def extract_details(&block)
78
120
  @detail_extractors << block
79
121
  end
122
+
123
+ private
124
+
125
+ def assert_unique_values!(map)
126
+ dupes = map.values.tally.select { |_, n| n > 1 }.keys
127
+ return if dupes.empty?
128
+
129
+ raise ArgumentError, "category values must be unique; collisions on #{dupes.inspect}"
130
+ end
80
131
  end
81
132
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ErrorRadar
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -17,6 +17,15 @@ ErrorRadar.configure do |config|
17
17
  # config.authenticate = ->(controller) { controller.send(:authenticate_admin!) }
18
18
  # config.current_user = ->(controller) { controller.current_admin&.email }
19
19
 
20
+ # --- Custom categories (optional) ---
21
+ # Built-in categories: application, external_api, background_job, syntax,
22
+ # database, network. Add your own app-specific ones here. The stored integer
23
+ # is a schema — keep it stable once you have data. Add lightly:
24
+ # config.register_category(:instagram_api, 6)
25
+ #
26
+ # Or replace the whole map at once (defaults are merged in first):
27
+ # config.categories = { instagram_api: 6, payments_api: 7 }
28
+
20
29
  # --- Custom classification ---
21
30
  # Map your own exception types to a category. First non-nil wins.
22
31
  # config.categorize { |e| :external_api if e.is_a?(MyApi::Error) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: error_radar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chienbn9x
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-18 00:00:00.000000000 Z
11
+ date: 2026-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails