munster 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11f34eb8fe918df292345851086c9190018d344bf73373125a1caec2e34984c8
4
- data.tar.gz: 51741866e336befe8d663cb27e225f8f9adff3552f3247437a11b3d0d966557d
3
+ metadata.gz: 2b1a49a264687c05fd36a4331d73d98218d8ff6fcf8f972384fe26db3182a2c5
4
+ data.tar.gz: 75102940fdd3d31b317f16fbe05ff8d9135aeed8229c45fb20445348719e7ccd
5
5
  SHA512:
6
- metadata.gz: 565266df3f8b518248b20ba6e5d7f12e420ee3cce7755f1d775a69c8ff3f99ef22db9d016051f23670f2b2e3326e72d17b28f0152641b052bf0a25daa4d04c12
7
- data.tar.gz: cc689a7151f3dcf888efd826f87697c7cd552d6804b1e082242abffb6d83c2e4285e51feec3c97761ff1e6c6a30ff58d28d7762239af30ea6d6264c2934cb291
6
+ metadata.gz: f61d40aa299eeed7a67f2998ed346f1655da7c2be4b87f3e2f7d4470b2e0c5eadee345a6fca3f98a2aa85d573ca079e8306b9b97dc2b96f260703159ac7e587c
7
+ data.tar.gz: d41554221b5c68ef67e8136bdf7904c6392466a79cf5d0f377e7f5bb8df37ae0b9311d0cbf34bdc5f44876c7e21cecb03e9311fac202d4b98b43a553e91f5e99
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ require: standard
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 3.0
5
+
6
+ inherit_gem:
7
+ standard: config/base.yml
8
+ # Don't define any actual rubocop config here - this file is only used for
9
+ # proper editor support, and not used on CI, formatters, nor anywhere else.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.2.0
2
+
3
+ - Handler methods are now defined as instance methods for simplicity.
4
+ - Define service_id in initializer with active_handlers, instead of handler class.
5
+ - Use ruby 3.0 as a base for standard/rubocop, format all code according to it.
6
+ - Introduce Rails common error reporter ( https://guides.rubyonrails.org/error_reporting.html )
7
+
1
8
  ## 0.1.0
2
9
 
3
10
  - Initial release
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Munster
2
+
2
3
  Munster is a Rails engine that provides a webhook endpoint for receiving and processing webhooks from various services. Engine stores received webhook first and later processes webhook in a separete async process.
3
4
 
4
5
  Source code is extracted from https://cheddar.me/ main service to be used in internal microservices. Code here could be a subject to change while we flesh out details.
@@ -16,6 +17,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
17
  $ gem install munster
17
18
 
18
19
  ## Usage
20
+
19
21
  Generate migrations and initializer file.
20
22
 
21
23
  `munster:install`
@@ -24,6 +26,24 @@ Mount munster engine in your routes.
24
26
 
25
27
  `mount Munster::Engine, at: "/webhooks"`
26
28
 
29
+ ## Requirements
30
+
31
+ This project depends on two dependencies:
32
+
33
+ - Ruby >= 3.0
34
+ - Rails >= 7.0
35
+
36
+ ## Error reporter
37
+
38
+ This gem uses [Rails common error reporter](https://guides.rubyonrails.org/error_reporting.html) to report any possible error to services like Honeybadger, Appsignal, Sentry and etc. Most of those services already support this common interface, if not - it's not that hard to add this support on your own.
39
+
40
+ It's possible to provide additional context for every error. e.g.
41
+ ```
42
+ Munster.configure do |config|
43
+ config.error_context = { appsignal: { namespace: "webhooks" } }
44
+ end
45
+ ```
46
+
27
47
  ## Development
28
48
 
29
49
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/example/Gemfile CHANGED
@@ -6,7 +6,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
6
6
  ruby "3.2.2"
7
7
 
8
8
  # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
9
- gem "rails", "~> 7.0.8", ">= 7.0.8.1"
9
+ gem "rails", ">= 7.0.8.1"
10
10
 
11
11
  # The modern asset pipeline for Rails [https://github.com/rails/propshaft]
12
12
  gem "propshaft"
data/example/Gemfile.lock CHANGED
@@ -2,83 +2,96 @@ PATH
2
2
  remote: ..
3
3
  specs:
4
4
  munster (0.1.0)
5
- rails (~> 7.0)
5
+ rails (~> 7.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actioncable (7.0.8.1)
11
- actionpack (= 7.0.8.1)
12
- activesupport (= 7.0.8.1)
10
+ actioncable (7.1.3.3)
11
+ actionpack (= 7.1.3.3)
12
+ activesupport (= 7.1.3.3)
13
13
  nio4r (~> 2.0)
14
14
  websocket-driver (>= 0.6.1)
15
- actionmailbox (7.0.8.1)
16
- actionpack (= 7.0.8.1)
17
- activejob (= 7.0.8.1)
18
- activerecord (= 7.0.8.1)
19
- activestorage (= 7.0.8.1)
20
- activesupport (= 7.0.8.1)
15
+ zeitwerk (~> 2.6)
16
+ actionmailbox (7.1.3.3)
17
+ actionpack (= 7.1.3.3)
18
+ activejob (= 7.1.3.3)
19
+ activerecord (= 7.1.3.3)
20
+ activestorage (= 7.1.3.3)
21
+ activesupport (= 7.1.3.3)
21
22
  mail (>= 2.7.1)
22
23
  net-imap
23
24
  net-pop
24
25
  net-smtp
25
- actionmailer (7.0.8.1)
26
- actionpack (= 7.0.8.1)
27
- actionview (= 7.0.8.1)
28
- activejob (= 7.0.8.1)
29
- activesupport (= 7.0.8.1)
26
+ actionmailer (7.1.3.3)
27
+ actionpack (= 7.1.3.3)
28
+ actionview (= 7.1.3.3)
29
+ activejob (= 7.1.3.3)
30
+ activesupport (= 7.1.3.3)
30
31
  mail (~> 2.5, >= 2.5.4)
31
32
  net-imap
32
33
  net-pop
33
34
  net-smtp
34
- rails-dom-testing (~> 2.0)
35
- actionpack (7.0.8.1)
36
- actionview (= 7.0.8.1)
37
- activesupport (= 7.0.8.1)
38
- rack (~> 2.0, >= 2.2.4)
35
+ rails-dom-testing (~> 2.2)
36
+ actionpack (7.1.3.3)
37
+ actionview (= 7.1.3.3)
38
+ activesupport (= 7.1.3.3)
39
+ nokogiri (>= 1.8.5)
40
+ racc
41
+ rack (>= 2.2.4)
42
+ rack-session (>= 1.0.1)
39
43
  rack-test (>= 0.6.3)
40
- rails-dom-testing (~> 2.0)
41
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
42
- actiontext (7.0.8.1)
43
- actionpack (= 7.0.8.1)
44
- activerecord (= 7.0.8.1)
45
- activestorage (= 7.0.8.1)
46
- activesupport (= 7.0.8.1)
44
+ rails-dom-testing (~> 2.2)
45
+ rails-html-sanitizer (~> 1.6)
46
+ actiontext (7.1.3.3)
47
+ actionpack (= 7.1.3.3)
48
+ activerecord (= 7.1.3.3)
49
+ activestorage (= 7.1.3.3)
50
+ activesupport (= 7.1.3.3)
47
51
  globalid (>= 0.6.0)
48
52
  nokogiri (>= 1.8.5)
49
- actionview (7.0.8.1)
50
- activesupport (= 7.0.8.1)
53
+ actionview (7.1.3.3)
54
+ activesupport (= 7.1.3.3)
51
55
  builder (~> 3.1)
52
- erubi (~> 1.4)
53
- rails-dom-testing (~> 2.0)
54
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
55
- activejob (7.0.8.1)
56
- activesupport (= 7.0.8.1)
56
+ erubi (~> 1.11)
57
+ rails-dom-testing (~> 2.2)
58
+ rails-html-sanitizer (~> 1.6)
59
+ activejob (7.1.3.3)
60
+ activesupport (= 7.1.3.3)
57
61
  globalid (>= 0.3.6)
58
- activemodel (7.0.8.1)
59
- activesupport (= 7.0.8.1)
60
- activerecord (7.0.8.1)
61
- activemodel (= 7.0.8.1)
62
- activesupport (= 7.0.8.1)
63
- activestorage (7.0.8.1)
64
- actionpack (= 7.0.8.1)
65
- activejob (= 7.0.8.1)
66
- activerecord (= 7.0.8.1)
67
- activesupport (= 7.0.8.1)
62
+ activemodel (7.1.3.3)
63
+ activesupport (= 7.1.3.3)
64
+ activerecord (7.1.3.3)
65
+ activemodel (= 7.1.3.3)
66
+ activesupport (= 7.1.3.3)
67
+ timeout (>= 0.4.0)
68
+ activestorage (7.1.3.3)
69
+ actionpack (= 7.1.3.3)
70
+ activejob (= 7.1.3.3)
71
+ activerecord (= 7.1.3.3)
72
+ activesupport (= 7.1.3.3)
68
73
  marcel (~> 1.0)
69
- mini_mime (>= 1.1.0)
70
- activesupport (7.0.8.1)
74
+ activesupport (7.1.3.3)
75
+ base64
76
+ bigdecimal
71
77
  concurrent-ruby (~> 1.0, >= 1.0.2)
78
+ connection_pool (>= 2.2.5)
79
+ drb
72
80
  i18n (>= 1.6, < 2)
73
81
  minitest (>= 5.1)
82
+ mutex_m
74
83
  tzinfo (~> 2.0)
84
+ base64 (0.2.0)
85
+ bigdecimal (3.1.8)
75
86
  builder (3.2.4)
76
87
  concurrent-ruby (1.2.3)
88
+ connection_pool (2.4.1)
77
89
  crass (1.0.6)
78
90
  date (3.3.4)
79
91
  debug (1.9.2)
80
92
  irb (~> 1.10)
81
93
  reline (>= 0.3.8)
94
+ drb (2.2.1)
82
95
  erubi (1.12.0)
83
96
  globalid (1.2.1)
84
97
  activesupport (>= 6.1)
@@ -97,9 +110,9 @@ GEM
97
110
  net-pop
98
111
  net-smtp
99
112
  marcel (1.0.4)
100
- method_source (1.1.0)
101
113
  mini_mime (1.1.5)
102
114
  minitest (5.22.3)
115
+ mutex_m (0.2.0)
103
116
  net-imap (0.4.11)
104
117
  date
105
118
  net-protocol
@@ -133,22 +146,27 @@ GEM
133
146
  nio4r (~> 2.0)
134
147
  racc (1.7.3)
135
148
  rack (2.2.9)
149
+ rack-session (1.0.2)
150
+ rack (< 3)
136
151
  rack-test (2.1.0)
137
152
  rack (>= 1.3)
138
- rails (7.0.8.1)
139
- actioncable (= 7.0.8.1)
140
- actionmailbox (= 7.0.8.1)
141
- actionmailer (= 7.0.8.1)
142
- actionpack (= 7.0.8.1)
143
- actiontext (= 7.0.8.1)
144
- actionview (= 7.0.8.1)
145
- activejob (= 7.0.8.1)
146
- activemodel (= 7.0.8.1)
147
- activerecord (= 7.0.8.1)
148
- activestorage (= 7.0.8.1)
149
- activesupport (= 7.0.8.1)
153
+ rackup (1.0.0)
154
+ rack (< 3)
155
+ webrick
156
+ rails (7.1.3.3)
157
+ actioncable (= 7.1.3.3)
158
+ actionmailbox (= 7.1.3.3)
159
+ actionmailer (= 7.1.3.3)
160
+ actionpack (= 7.1.3.3)
161
+ actiontext (= 7.1.3.3)
162
+ actionview (= 7.1.3.3)
163
+ activejob (= 7.1.3.3)
164
+ activemodel (= 7.1.3.3)
165
+ activerecord (= 7.1.3.3)
166
+ activestorage (= 7.1.3.3)
167
+ activesupport (= 7.1.3.3)
150
168
  bundler (>= 1.15.0)
151
- railties (= 7.0.8.1)
169
+ railties (= 7.1.3.3)
152
170
  rails-dom-testing (2.2.0)
153
171
  activesupport (>= 5.0.0)
154
172
  minitest
@@ -156,13 +174,14 @@ GEM
156
174
  rails-html-sanitizer (1.6.0)
157
175
  loofah (~> 2.21)
158
176
  nokogiri (~> 1.14)
159
- railties (7.0.8.1)
160
- actionpack (= 7.0.8.1)
161
- activesupport (= 7.0.8.1)
162
- method_source
177
+ railties (7.1.3.3)
178
+ actionpack (= 7.1.3.3)
179
+ activesupport (= 7.1.3.3)
180
+ irb
181
+ rackup (>= 1.0.0)
163
182
  rake (>= 12.2)
164
- thor (~> 1.0)
165
- zeitwerk (~> 2.5)
183
+ thor (~> 1.0, >= 1.2.2)
184
+ zeitwerk (~> 2.6)
166
185
  rake (13.2.1)
167
186
  rdoc (6.6.3.1)
168
187
  psych (>= 4.0.0)
@@ -179,6 +198,7 @@ GEM
179
198
  timeout (0.4.1)
180
199
  tzinfo (2.0.6)
181
200
  concurrent-ruby (~> 1.0)
201
+ webrick (1.8.1)
182
202
  websocket-driver (0.7.6)
183
203
  websocket-extensions (>= 0.1.0)
184
204
  websocket-extensions (0.1.5)
@@ -197,7 +217,7 @@ DEPENDENCIES
197
217
  munster!
198
218
  propshaft
199
219
  puma (~> 5.0)
200
- rails (~> 7.0.8, >= 7.0.8.1)
220
+ rails (>= 7.0.8.1)
201
221
  sqlite3 (~> 1.4)
202
222
  tzinfo-data
203
223
 
@@ -4,25 +4,16 @@
4
4
  # if a banking provider test fails, indicating that the bank might be having an incident
5
5
 
6
6
  class WebhookTestHandler < Munster::BaseHandler
7
- def self.valid?(request)
8
- true
9
- end
7
+ def valid?(request) = true
10
8
 
11
- def self.process(webhook)
9
+ def process(webhook)
12
10
  return unless webhook.received?
13
11
  webhook.update!(status: "processing")
14
- wait(5)
15
12
  webhook.update!(status: "processed")
16
13
  rescue
17
- webhook.update!(status: "received")
14
+ webhook.update!(status: "error")
18
15
  raise
19
16
  end
20
17
 
21
- def self.service_id
22
- :test
23
- end
24
-
25
- def self.expose_errors_to_sender?
26
- true
27
- end
18
+ def expose_errors_to_sender? = true
28
19
  end
@@ -61,7 +61,7 @@ Rails.application.configure do
61
61
  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name")
62
62
 
63
63
  if ENV["RAILS_LOG_TO_STDOUT"].present?
64
- logger = ActiveSupport::Logger.new(STDOUT)
64
+ logger = ActiveSupport::Logger.new($stdout)
65
65
  logger.formatter = config.log_formatter
66
66
  config.logger = ActiveSupport::TaggedLogging.new(logger)
67
67
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../app/webhooks/test_handler"
3
+ require_relative "../../app/webhooks/webhook_test_handler"
4
4
 
5
5
  Munster.configure do |config|
6
6
  config.active_handlers = [WebhookTestHandler]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.routes.draw do
4
- mount Munster::Engine, at: "/webhooks"
4
+ mount Munster::Engine, at: "/webhooks", as: "webhooks"
5
5
  end
@@ -4,64 +4,59 @@ require_relative "jobs/processing_job"
4
4
 
5
5
  module Munster
6
6
  class BaseHandler
7
- class << self
8
- # Reimplement this method, it's being used in WebhooksController to store incoming webhook.
9
- # Also que for processing in the end.
10
- # @return [void]
11
- def handle(action_dispatch_request)
12
- binary_body_str = action_dispatch_request.body.read.force_encoding(Encoding::BINARY)
13
- attrs = {
14
- body: binary_body_str,
15
- handler_module_name: name,
16
- handler_event_id: extract_event_id_from_request(action_dispatch_request)
17
- }
18
- webhook = Munster::ReceivedWebhook.create!(**attrs)
19
-
20
- Munster.configuration.processing_job_class.perform_later(webhook)
21
- rescue ActiveRecord::RecordNotUnique # Deduplicated
22
- nil
23
- end
7
+ # Gets called from the background job
8
+ def self.process(...)
9
+ new.process(...)
10
+ end
24
11
 
25
- # This method will be used to process webhook by async worker.
26
- def process(received_webhook)
27
- end
12
+ # Reimplement this method, it's being used in WebhooksController to store incoming webhook.
13
+ # Also que for processing in the end.
14
+ # @return [void]
15
+ def handle(action_dispatch_request)
16
+ binary_body_str = action_dispatch_request.body.read.force_encoding(Encoding::BINARY)
17
+ attrs = {
18
+ body: binary_body_str,
19
+ handler_module_name: self.class.name,
20
+ handler_event_id: extract_event_id_from_request(action_dispatch_request)
21
+ }
22
+ webhook = Munster::ReceivedWebhook.create!(**attrs)
23
+
24
+ Munster.configuration.processing_job_class.perform_later(webhook)
25
+ rescue ActiveRecord::RecordNotUnique # Deduplicated
26
+ nil
27
+ end
28
28
 
29
- # This should be defined for each webhook handler and should be unique.
30
- # Otherwise controller will never pick up, that this handler exists.
31
- #
32
- # Please consider that this will be used in url, so don't use underscores or any other symbols that are not used in URL.
33
- def service_id
34
- :base
35
- end
29
+ # This method will be used to process webhook by async worker.
30
+ def process(received_webhook)
31
+ end
36
32
 
37
- # This method verifies that request actually comes from provider:
38
- # signature validation, HTTP authentication, IP whitelisting and the like
39
- def valid?(action_dispatch_request)
40
- true
41
- end
33
+ # This method verifies that request actually comes from provider:
34
+ # signature validation, HTTP authentication, IP whitelisting and the like
35
+ def valid?(action_dispatch_request)
36
+ true
37
+ end
42
38
 
43
- # Default implementation just generates UUID, but if the webhook sender sends us
44
- # an event ID we use it for deduplication.
45
- def extract_event_id_from_request(action_dispatch_request)
46
- SecureRandom.uuid
47
- end
39
+ # Default implementation just generates UUID, but if the webhook sender sends us
40
+ # an event ID we use it for deduplication.
41
+ def extract_event_id_from_request(action_dispatch_request)
42
+ SecureRandom.uuid
43
+ end
48
44
 
49
- # Webhook senders have varying retry behaviors, and often you want to "pretend"
50
- # everything is fine even though there is an error so that they keep sending you
51
- # data and do not disable your endpoint forcibly. We allow this to be configured
52
- # on a per-handler basis - a better webhooks sender will be able to make out
53
- # some sense of the errors.
54
- def expose_errors_to_sender?
55
- false
56
- end
45
+ # Webhook senders have varying retry behaviors, and often you want to "pretend"
46
+ # everything is fine even though there is an error so that they keep sending you
47
+ # data and do not disable your endpoint forcibly. We allow this to be configured
48
+ # on a per-handler basis - a better webhooks sender will be able to make out
49
+ # some sense of the errors.
50
+ def expose_errors_to_sender?
51
+ false
52
+ end
57
53
 
58
- # Tells the controller whether this handler is active or not. This can be used
59
- # to deactivate a particular handler via feature flags for example, or use other
60
- # logic to determine whether the handler may be used to create new received webhooks
61
- # in the system. This is primarily needed for load shedding.
62
- def active?
63
- true
64
- end
54
+ # Tells the controller whether this handler is active or not. This can be used
55
+ # to deactivate a particular handler via feature flags for example, or use other
56
+ # logic to determine whether the handler may be used to create new received webhooks
57
+ # in the system. This is primarily needed for load shedding.
58
+ def active?
59
+ true
65
60
  end
66
61
  end
67
62
  end
@@ -5,22 +5,22 @@ module Munster
5
5
  class HandlerRefused < StandardError
6
6
  end
7
7
 
8
+ class HandlerInactive < StandardError
9
+ end
10
+
8
11
  def create
9
- handler = lookup_handler(params[:service_id])
10
- return render_error("Webhook handler is inactive", :service_unavailable) unless handler.active?
12
+ handler = lookup_handler(params[:service_id]).new
11
13
 
14
+ raise HandlerInactive unless handler.active?
12
15
  raise HandlerRefused unless handler.valid?(request)
13
16
 
14
- # FIXME: Duplicated webhook will be overwritten here and processing job will be quite for second time.
15
- # This will generate a following error in this case:
16
- # Error performing Munster::ProcessingJob (Job ID: b40f3f28-81be-4c99-bce8-9ad879ec9754) from Async(default) in 9.95ms: ActiveRecord::RecordInvalid (Validation failed: Status Invalid transition from processing to received):
17
- #
18
- # This should be handled properly.
19
17
  handler.handle(request)
20
18
  head :ok
19
+ rescue KeyError # handler was not found, so we return generic 404 error.
20
+ render_error("Required parameters were not present in the request", :not_found)
21
21
  rescue => e
22
- # TODO: add exception handler here
23
- # Appsignal.add_exception(e)
22
+ Rails.error.set_context(**Munster.configuration.error_context)
23
+ Rails.error.report(e)
24
24
 
25
25
  if handler&.expose_errors_to_sender?
26
26
  error_for_sender_from_exception(e)
@@ -33,8 +33,10 @@ module Munster
33
33
  case e
34
34
  when HandlerRefused
35
35
  render_error("Webhook handler did not validate the request (signature or authentication may be invalid)", :forbidden)
36
- when JSON::ParserError, KeyError
37
- render_error("Required parameters were not present in the request or the request body was not valid JSON", :bad_request)
36
+ when HandlerInactive
37
+ render_error("Webhook handler is inactive", :service_unavailable)
38
+ when JSON::ParserError
39
+ render_error("Request body is not a valid JSON", :bad_request)
38
40
  else
39
41
  render_error("Internal error", :internal_server_error)
40
42
  end
@@ -42,11 +44,11 @@ module Munster
42
44
 
43
45
  def render_error(message_str, status_sym)
44
46
  json = {error: message_str}.to_json
45
- render(json:, status: status_sym)
47
+ render(json: json, status: status_sym)
46
48
  end
47
49
 
48
50
  def lookup_handler(service_id_str)
49
- Munster.configuration.active_handlers.index_by(&:service_id).fetch(service_id_str.to_sym)
51
+ Munster.configuration.active_handlers.with_indifferent_access.fetch(service_id_str)
50
52
  end
51
53
  end
52
54
  end
@@ -1,4 +1,28 @@
1
1
  Munster.configure do |config|
2
- config.active_handlers = []
3
- config.processing_job_class = Munster::ProcessingJob
2
+ # Active Handlers are defined as hash with key as a service_id and handler class that would handle webhook request.
3
+ # Example:
4
+ # {:test => TestHandler, :inactive => InactiveHandler}
5
+ config.active_handlers = {}
6
+
7
+ # It's possible to overwrite default processing job to enahance it. As example if you want to add proper locking or retry mechanism.
8
+ #
9
+ # Example:
10
+ #
11
+ # class WebhookProcessingJob < Munster::ProcessingJob
12
+ # def perform(webhook)
13
+ # TokenLock.with(name: "webhook-processing-#{webhook.id}") do
14
+ # super(webhook)
15
+ # end
16
+ # end
17
+ #
18
+ # This is how you can change processing job:
19
+ #
20
+ # config.processing_job_class = WebhookProcessingJob
21
+
22
+ # We're using a common interface for error reporting provided by Rails, e.g Rails.error.report. In some cases
23
+ # you want to enhance those errors with additional context. As example to provide a namespace:
24
+ #
25
+ # { appsignal: { namespace: "webhooks" } }
26
+ #
27
+ # config.error_context = { appsignal: { namespace: "webhooks" } }
4
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Munster
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/munster.rb CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  require_relative "munster/version"
4
4
  require_relative "munster/engine"
5
- require "active_support/configurable"
6
5
  require_relative "munster/jobs/processing_job"
6
+ require "active_support/configurable"
7
7
 
8
8
  module Munster
9
9
  def self.configuration
@@ -20,4 +20,5 @@ class Munster::Configuration
20
20
 
21
21
  config_accessor(:processing_job_class) { Munster::ProcessingJob }
22
22
  config_accessor(:active_handlers) { [] }
23
+ config_accessor(:error_context) { {} }
23
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: munster
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
  - Stanislav Katkov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-03 00:00:00.000000000 Z
11
+ date: 2024-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".editorconfig"
91
+ - ".rubocop.yml"
91
92
  - ".standard.yml"
92
93
  - CHANGELOG.md
93
94
  - LICENSE
@@ -110,7 +111,7 @@ files:
110
111
  - example/app/models/application_record.rb
111
112
  - example/app/models/concerns/.keep
112
113
  - example/app/views/layouts/application.html.erb
113
- - example/app/webhooks/test_handler.rb
114
+ - example/app/webhooks/webhook_test_handler.rb
114
115
  - example/bin/bundle
115
116
  - example/bin/rails
116
117
  - example/bin/rake