diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 83889619..5dea17b5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,6 +7,7 @@ class ApplicationController < ActionController::Base protect_from_forgery(with: :exception) before_action :invite_link + before_action :prepare_exception_notifier after_action :allow_embedding def default_serializer_options @@ -82,4 +83,10 @@ class ApplicationController < ActionController::Base # or allow a whitelist # response.headers['X-Frame-Options'] = 'ALLOW-FROM http://blog.metamaps.cc' end + + def prepare_exception_notifier + request.env['exception_notifier.exception_data'] = { + current_user: current_user + } + end end diff --git a/config/initializers/exception_notification.rb b/config/initializers/exception_notification.rb index db508b3c..a6c0d2b1 100644 --- a/config/initializers/exception_notification.rb +++ b/config/initializers/exception_notification.rb @@ -1,6 +1,51 @@ # frozen_string_literal: true require 'exception_notification/rails' +module ExceptionNotifier + class MetamapsNotifier < SlackNotifier + def call(exception, options = {}) + # trick original notifier to "ping" self, storing the result + # in @message_opts and then modifying the result + @old_notifier = @notifier + @notifier = self + super + @notifier = @old_notifier + + @message_opts[:attachments][0][:fields] = new_fields(exception, options[:env]) + @message_opts[:attachments][0][:text] = new_text(exception, options[:env]) + + @notifier.ping '', @message_opts + end + + def ping(message, message_opts) + @message = message + @message_opts = message_opts + end + + private + + def new_fields(exception, env) + new_fields = [] + + backtrace = exception.backtrace.reject { |line| line !~ %r{metamaps/(app|config|lib)} } + backtrace = backtrace[0..3] if backtrace.length > 4 + backtrace = "```\n#{backtrace.join("\n")}\n```" + new_fields << { title: 'Backtrace', value: backtrace } + + user = env.dig('exception_notifier.exception_data', :current_user) + new_fields << { title: 'Current User', value: "`#{user.name} <#{user.email}>`" } + + new_fields + end + + def new_text(exception, _env) + text = @message_opts[:attachments][0][:text].chomp + text += ': ' + exception.message + "\n" + text + end + end +end + ExceptionNotification.configure do |config| # Ignore additional exception types. # ActiveRecord::RecordNotFound, AbstractController::ActionNotFound and @@ -20,7 +65,7 @@ ExceptionNotification.configure do |config| # Notifiers ###### if ENV['SLACK_EN_WEBHOOK_URL'] - config.add_notifier :slack, webhook_url: ENV['SLACK_EN_WEBHOOK_URL'] + config.add_notifier :metamaps, webhook_url: ENV['SLACK_EN_WEBHOOK_URL'] end # Email notifier sends notifications by email.