@@ 10,6 10,9 @@ require "dhall"
require "em-hiredis"
require "em_promise"
require "ruby-bandwidth-iris"
+require "sentry-ruby"
+
+Sentry.init
CONFIG =
Dhall::Coder
@@ 42,6 45,17 @@ BandwidthIris::Client.global_options = {
password: CONFIG[:creds][:password]
}
+def new_sentry_hub(stanza, name: nil)
+ hub = Sentry.get_current_hub&.new_from_top
+ raise "Sentry.init has not been called" unless hub
+
+ hub.push_scope
+ hub.current_scope.clear_breadcrumbs
+ hub.current_scope.set_transaction_name(name) if name
+ hub.current_scope.set_user(jid: stanza.from.stripped.to_s)
+ hub
+end
+
# Braintree is not async, so wrap in EM.defer for now
class AsyncBraintree
def initialize(environment:, merchant_id:, public_key:, private_key:, **)
@@ 79,10 93,15 @@ end
BRAINTREE = AsyncBraintree.new(**CONFIG[:braintree])
-def panic(e)
+def panic(e, hub=nil)
m = e.respond_to?(:message) ? e.message : e
warn "Error raised during event loop: #{e.class}: #{m}"
warn e.backtrace if e.respond_to?(:backtrace)
+ if e.is_a?(::Exception)
+ (hub || Sentry).capture_exception(e, hint: { background: false })
+ else
+ (hub || Sentry).capture_message(e, hint: { background: false })
+ end
exit 1
end
@@ 121,13 140,25 @@ message to: /\Aaccount@/ do |m|
end
message to: /\Acustomer_/, from: /@#{CONFIG[:sgx]}(\/|\Z)/ do |m|
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
Customer.for_customer_id(
m.to.node.delete_prefix("customer_")
- ).then { |customer| customer.stanza_to(m) }.catch(&method(:panic))
+ ).then { |customer|
+ sentry_hub.current_scope.set_user(
+ id: customer.customer_id,
+ jid: iq.from.stripped.to_s
+ )
+ customer.stanza_to(m)
+ }.catch { |e| panic(e, sentry_hub) }
end
message do |m|
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
Customer.for_jid(m.from.stripped).then { |customer|
+ sentry_hub.current_scope.set_user(
+ id: customer.customer_id,
+ jid: iq.from.stripped.to_s
+ )
today = Time.now.utc.to_date
EMPromise.all([
REDIS.zremrangebylex(
@@ 143,7 174,7 @@ message do |m|
),
customer.stanza_from(m)
])
- }.catch(&method(:panic))
+ }.catch { |e| panic(e, sentry_hub) }
end
message :error? do |m|
@@ 228,15 259,28 @@ disco_items node: "http://jabber.org/protocol/commands" do |iq|
end
command :execute?, node: "jabber:iq:register", sessionid: nil do |iq|
- Customer.for_jid(iq.from.stripped).catch {
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
+ EMPromise.resolve(nil).then {
+ Customer.for_jid(iq.from.stripped)
+ }.catch {
+ sentry_hub.add_breadcrumb(Sentry::Breadcrumb.new(
+ message: "Customer.create"
+ ))
Customer.create(iq.from.stripped)
}.then { |customer|
+ sentry_hub.current_scope.set_user(
+ id: customer.customer_id,
+ jid: iq.from.stripped.to_s
+ )
+ sentry_hub.add_breadcrumb(Sentry::Breadcrumb.new(
+ message: "Registration.for"
+ ))
Registration.for(
iq,
customer,
web_register_manager
).then(&:write)
- }.catch(&method(:panic))
+ }.catch { |e| panic(e, sentry_hub) }
end
def reply_with_note(iq, text, type: :info)
@@ 249,6 293,7 @@ def reply_with_note(iq, text, type: :info)
end
command :execute?, node: "buy-credit", sessionid: nil do |iq|
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
reply = iq.reply
reply.allowed_actions = [:complete]
@@ 265,12 310,14 @@ command :execute?, node: "buy-credit", sessionid: nil do |iq|
}.then { |amount|
reply_with_note(iq, "$#{'%.2f' % amount} added to your account balance.")
}.catch { |e|
+ sentry_hub.capture_exception(e)
text = "Failed to buy credit, system said: #{e.message}"
reply_with_note(iq, text, type: :error)
- }.catch(&method(:panic))
+ }.catch { |e| panic(e, sentry_hub) }
end
command :execute?, node: "web-register", sessionid: nil do |iq|
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
jid = iq.form.field("jid")&.value.to_s.strip
tel = iq.form.field("tel")&.value.to_s.strip
if iq.from.stripped != CONFIG[:web_register][:from]
@@ 284,11 331,11 @@ command :execute?, node: "web-register", sessionid: nil do |iq|
cmd.node = "push-register"
cmd.form.fields = [var: "to", value: jid]
cmd.form.type = "submit"
- }).then do |result|
+ }).then { |result|
final_jid = result.form.field("from")&.value.to_s.strip
web_register_manager[final_jid] = tel
BLATHER << iq.reply.tap { |reply| reply.status = :completed }
- end
+ }.catch { |e| panic(e, sentry_hub) }
end
end