Pular para o conteúdo principal
Por padrão, o AppSignal tenta registrar o máximo possível de exceções (erros). Com nossas integrações para muitos frameworks e gems de background jobs, poucas exceções passarão despercebidas. Na maioria dos casos, erros não causados por bugs no seu código ocorrem quando seu app interage com o mundo real. Bots podem aparecer e tentar postar formulários automaticamente; links desatualizados podem direcionar visitantes para conteúdo que não existe mais, e assim por diante. Para evitar que esses erros sejam levantados como problemas no AppSignal, é possível adicionar tratamento de exceções ao seu código ou até mesmo deixar o AppSignal ignorar completamente erros específicos.

Ignorar erros

A configuração do AppSignal torna possível ignorar erros. Ao fornecer uma lista de erros específicos, o AppSignal não enviará alertas quando esses erros forem levantados.

Tratamento de exceções

Apenas ignorar um erro silenciará as notificações, mas poderia potencialmente ocultar um problema maior. Por essa razão, recomendamos que você adicione tratamento de exceções com blocos begin .. rescue em sua aplicação. Usando begin .. rescue você pode capturar exceções específicas e adicionar um caminho de código alternativo para quando uma exceção ocorre, como renderizar páginas 404 ou fornecer ao usuário mensagens de erro mais detalhadas sobre o que deu errado.
begin
  user = Post.find(1)
rescue RecordNotFound => e
  render :text => "Could not find post", :status => 404
end
Existem alguns cenários que devem ser tratados dessa forma para fornecer respostas HTTP apropriadas quando recursos não existem ou quando uma submissão de formulário falha. Leia nosso primer sobre Tratamento de exceções para mais informações sobre como funciona e como implementá-lo corretamente.

Rails rescue_from

O Rails fornece um mecanismo para tratar exceções no nível do controller. Ao definir uma declaração rescue_from para um erro específico, é possível criar um caminho de código alternativo para quando essa exceção é levantada. Como isso pode ser definido em qualquer nível de controller, isso possibilita adicionar tratamento de exceções em nível de aplicação.
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

  private

  def record_not_found
    render :text => "404: Resource not found", :status => 404
  end
end
Mais informações sobre rescue_from podem ser encontradas no guia do Rails sobre ActionController.

Lidar com 404s

Se um visitante acessar uma URL que não pode ser tratada pelo seu roteamento ou controller, o Rack e outros frameworks levantarão uma exceção. Geralmente é uma boa ideia tratar essas exceções com uma resposta 404 para seus usuários. Em controllers em que uma operação find é realizada com base em um parâmetro de uma URL, recomenda-se que você trate ActiveRecord::RecordNotFound (ou o equivalente no seu ORM de escolha) para também mostrar uma resposta 404. No entanto, isso pode ocultar bugs reais, então deve ser feito com cuidado.

Lidar com tokens de autenticidade inválidos

O Rails tem um mecanismo que protege seus formulários de serem preenchidos por bots com muita facilidade. Sempre que um formulário é postado sem um token de autenticidade correto, um ActionController::InvalidAuthenticityToken será levantado. Às vezes, usuários legítimos também podem encontrar esses erros, então é uma boa ideia ter uma página de erro separada explicando o que deu errado. Aconselhamos retornar essa página com uma resposta 422 (Unprocessable Entity).

Lidar com tentativas de hacking

Você pode ter erros porque bots ou hackers estão tentando explorar problemas de segurança como o notório exploit do YAML. Versões mais recentes do Rails levantarão um Hash::DisallowedType quando isso acontecer. Um RangeError também é frequentemente resultado de uma tentativa de hacking. Você poderia capturar esses tipos de erros e retornar uma resposta 403 (Forbidden).

Métodos helper de reporte de exceções

O AppSignal fornece uma única interface para reportar exceções com Appsignal.report_error. Se sua aplicação está usando a versão 3 ou mais antiga da gem Ruby, veja a seção de tratamento de exceções legado.

Appsignal.report_error

Aplicações podem ter tratamento de exceções onde não querem fazer o processo Ruby crashar. Ao adicionar tratamento de exceções, a exceção não vai mais propagar até a instrumentação do AppSignal. O AppSignal não reportará essas exceções. Se você quiser reportar a exceção sem fazer a aplicação crashar, use o helper Appsignal.report_error para reportá-la ao AppSignal de dentro do tratamento de exceções. Se uma Transaction do AppSignal estiver ativa, este helper adicionará a exceção à Transaction atual. As aplicações podem reportar múltiplas exceções em uma Transaction. Se nenhuma Transaction estiver ativa, este helper criará uma nova Transaction e reportará a exceção na Transaction recém-criada. O AppSignal sempre reportará a exceção dessa forma ao usar Appsignal.report_error.
begin
  # Some code that raises an exception
rescue => error
  Appsignal.report_error(error)
  puts "Exiting. An error occurred: #{error}"
  exit 1
end

Adicionando metadados

Personalizar os metadados na Transaction para a exceção é possível passando um bloco para o helper Appsignal.report_error. Veja nossos guias de Tagging e Personalização de dados para mais informações sobre que tipo de dados podem ser adicionados neste bloco. Os metadados definidos no bloco do Appsignal.report_error só se aplicam à exceção fornecida ao helper. Metadados definidos fora dos blocos do Appsignal.report_error são adicionados a todas as exceções se houver uma transaction ativa.
begin
  # some code
rescue => error
  Appsignal.report_error(error) do
    Appsignal.set_namespace("admin")
    Appsignal.set_action("MyCustomAction#perform")
    Appsignal.add_params(:param1 => "value1", :param2 => "value2")
    Appsignal.add_tags(:tag1 => "value1", :tag2 => "value2")
    Appsignal.add_custom_data(
      :i18n => {
        :locale => "en_GB",
        :default_locale => "en_US"
      }
    )
  end
end

Reportando múltiplas exceções

Múltiplos erros podem ser reportados em uma Transaction, como uma action de controller do Rails tratando uma requisição HTTP ou um background job do Sidekiq. Um máximo de 10 erros pode ser definido em uma Transaction. Se várias exceções forem reportadas em uma Transaction, os metadados definidos no bloco do Appsignal.report_error só se aplicam à exceção fornecida ao helper. Metadados definidos fora dos blocos do Appsignal.report_error são adicionados a todas as exceções.
def index
  # This tag is added to all exceptions
  Appsignal.add_tags(:some_tag_for_all_errors => true)

  begin
    raise "something went wrong"
  rescue => error
    # Report the first exception
    Appsignal.report_error(error) do
      # This tag is only added to the first exception
      Appsignal.add_tags(:some_tag => true)
    end
  end

  begin
    raise "something else went wrong"
  rescue => error
    # Report the second exception
    Appsignal.report_error(error) do
      # This tag is only added to the second exception
      Appsignal.add_tags(:other_tag => true)
    end
  end

  # This tag is added to all exceptions
  Appsignal.add_tags(:another_tag_for_all_errors => true)
end

Reportar exceções que crasham um processo

Por padrão, o AppSignal reportará exceções que crasham um processo Ruby, desde que o AppSignal seja iniciado antes da exceção ocorrer.
# some_script.rb
require "appsignal"

Appsignal.start

raise "I will crash the process!"
Para desabilitar essa funcionalidade, defina a opção de configuração enable_at_exit_reporter como false.

Processos Ruby de curta duração

Ao reportar exceções de scripts Ruby, tarefas Rake, processos Ruby de curta duração, leia a documentação nessas páginas sobre quando chamar Appsignal.stop para garantir que todas as exceções sejam reportadas ao AppSignal.

Tratamento de exceções legado

Leia esta seção ao usar a gem AppSignal para Ruby versão 3 ou anterior. Para versões mais recentes da nossa gem Ruby, use o helper Appsignal.report_error. O AppSignal fornece dois métodos helper de reporte de exceções. Qual você usa dependerá do contexto do erro. Os métodos são:
  • set_error: O helper set_error define o erro na Transaction atualmente ativa. Se nenhuma transaction estiver ativa, nenhum erro é reportado. Definir um erro na transaction atualmente ativa sobrescreve qualquer erro previamente definido na transaction.
  • send_error: Use send_error para reportar erros quando nenhuma transaction do AppSignal estiver ativa.

Appsignal.set_error

Existem cenários em que você tem seu próprio tratamento de exceções e não quer fazer o processo Ruby crashar. Ao adicionar seu próprio tratamento de exceções, o erro não é mais propagado até a integração do AppSignal e, portanto, não é registrado automaticamente. Se você ainda quiser rastrear o erro, pode usar Appsignal.set_error para adicionar a exceção à Transaction atual do AppSignal. O erro será registrado no AppSignal, mas seu processo não vai crashar.
require "yaml"
class SomeClass
  def call
    YAML.load(File.read("config.yml"))
  rescue SystemCallError => exception
    Appsignal.set_error(exception)
    puts "No config file found. Using defaults."
  end
end
A exceção será rastreada pelo AppSignal como qualquer outro erro, e permite que você forneça tratamento de erros personalizado e fallbacks. Chamar set_error só funciona quando há uma transaction do AppSignal ativa. Caso contrário, o erro será ignorado. Uma transaction está ativa na maioria das nossas integrações suportadas automaticamente e ao usar Appsignal.monitor ou Appsignal.monitor_transaction. Para mais informações sobre quando usar Appsignal.monitor_transaction, veja nosso guia de instrumentação para scripts e background jobs. Veja Appsignal.send_error para enviar erros sem uma transaction do AppSignal.
require "yaml"

Appsignal.monitor :action => "My action" do
  begin
    YAML.load(File.read("config.yml"))
  rescue SystemCallError => exception
    Appsignal.set_error(exception)
    puts "No config file found. Using defaults."
  end
end

Appsignal.send_error

O AppSignal fornece um mecanismo para enviar erros ao AppSignal sem precisar iniciar uma transaction. Isso é útil para rastrear erros que ocorrem em código que não está em um contexto de web ou background job, como tarefas Rake ou scripts Ruby separados. Isso é útil para instrumentação que não cria automaticamente transactions do AppSignal para perfilar, como nossas integrações. Você pode usar o método Appsignal.send_error para enviar diretamente uma exceção ao AppSignal de qualquer lugar do seu código sem primeiro iniciar uma transaction do AppSignal com Appsignal.monitor.
begin
  # some code
rescue => e
  Appsignal.send_error(e)
end

Adicionando metadados

Na gem AppSignal para Ruby 2.9 e mais nova, um bloco adicional pode ser passado ao método Appsignal.send_error para adicionar mais metadados à transaction de erro. Isso inclui metadados como o nome da action e parâmetros. Versões mais antigas da gem Ruby não permitirão que metadados adicionais sejam definidos.
begin
  # some code
rescue => e
  Appsignal.send_error(e) do |transaction|
    transaction.set_action("my_action")
    transaction.set_namespace("my_namespace")
    transaction.params = { :time => Time.now.utc }
  end
end

Appsignal.listen_for_error

Este helper foi removido na versão 4 da gem Ruby. Em vez disso, use um bloco rescue do Ruby com o helper Appsignal.report_error.
Uma forma alternativa de rastrear erros com o AppSignal é envolver código que pode levantar uma exceção em um bloco listen_for_error. Se uma exceção for levantada dentro desse bloco, ela é automaticamente rastreada pelo AppSignal e re-lançada. Isso permite que a aplicação e os frameworks tratem a exceção normalmente.
require "rake"
require "appsignal"

task :fail do
  Appsignal.listen_for_error do
    raise "I am an exception in a Rake task"
  end
end