~singpolyma/sgx-jmp

c9a8aa5d0833538b3f81a7e6d43e6cfcc5337f7b — Stephen Paul Weber 10 days ago 7794a8e
Add Sentry

Capture in #panic and a few other places, add customer and route context
as well as some initial breadcrumbs in the register command.
2 files changed, 56 insertions(+), 8 deletions(-)

M Gemfile
M sgx_jmp.rb
M Gemfile => Gemfile +1 -0
@@ 13,6 13,7 @@ gem "em_promise.rb", "~> 0.0.2"
gem "eventmachine"
gem "money-open-exchange-rates"
gem "ruby-bandwidth-iris"
gem "sentry-ruby"

group(:development) do
	gem "pry-reload"

M sgx_jmp.rb => sgx_jmp.rb +55 -8
@@ 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