#91 Custom Error Pages with Slack Notification
7-30-2017

Summary

Learn to use custom error pages to provide a similar look to your application. Get notified on Slack as errors occur to act on them before they're reported.
10
rails api error background processing 9:06 min

Summary

config/environments/development.rbconfig.consider_all_requests_local = false
config/application.rbconfig.exceptions_app = self.routes
config/routes.rbmatch "/404", to: "errors#not_found", via: :all
match "/500", to: "errors#internal_server_error", via: :all
errors_controller.rbclass ErrorsController < ApplicationController
  # layout 'errors'

  def not_found
  end

  def internal_server_error
    begin
      exception = request.env['action_dispatch.exception']
      message = exception.message.to_s
      source_extract = exception.source_extract.join("\n")
      backtrace = exception.backtrace[0..9].join("\n")
      SlackNotifyJob.perform_later(message, source_extract, backtrace)
    ensure
      # head :internal_server_error
      render status: 500
    end
  end
end
Gemfilegem "slack-notifier"
Terminalrail g job SlackNotify
jobs/slack_notify_job.rbclass SlackNotifyJob < ApplicationJob
  queue_as :default

  def perform(error_message, source_extract, backtrace)
    error = "Error: 500 - Internal Server Error"
    message = ""
    message << "*#{error}*\n"
    message << "*Date:* #{Time.now}\n"
    message << "*Error:* ```#{error_message}``` \n"
    message << "*Source:* ```#{source_extract}``` \n"
    message << "*Backtrace*: ```#{backtrace}``` \n"
    notifier = Slack::Notifier.new Rails.application.secrets.slack_url
    notifier.ping message, username: '091Error', channel: '#general'
  end
end


Photo
Sam Van Damme said 5 months ago:

Awesome, I could really use this.

Thanks!

Photo
Rocela Durazo Verdugo said 5 months ago:

Nice video, thank you :-)

386234?v=4&s=64
yuki24 said 4 months ago:

This pattern is extremely error-prone. There was once a section for implementing custom error pages in the official Rails guides that basically suggested the same approach as this episode, which was later removed because of potential issues it could introduce. In this episode specifically, there is a number of potential issues:

  • It doesn't filter or summarize exception details at all, so depending on how an exception is raised the app would end up brute forcing your slack channel with a lot of noisy events
  • self.routes only responds to 404 and 500 and can't handle any other HTTP statuses, which results in ActionController::RoutingError in the case of e.g. ActionController::MethodNotAllowed that is mapped to 405 (good luck on adding every single status to config/routes.rb)
  • If the SlackNotifyJob is configured to use an external queue (e.g. sidekiq, RabbitMQ) and an exception occurs due to that queue, it would raise an exception again and show an empty error page to the user (this is actually taken care of with a begin ... rescue ... end block, but still this is an issue that shouldn't exist)
  • The ErrorsController inherits from ApplicationController. This means that if the ApplicationController raises an exception in a before_action, the ErrorsController would raise the same exception again, which results in the same empty error page situation

A much better way would be to use a service like Sentry and configure it to send events to your slack channel.

Login to Comment