> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tratamento de exceções

export const Compatibility = ({versions = [], label = "Available in"}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const defaultPillStyle = {
    borderColor: "#d4d4d8",
    background: "#f4f4f5",
    color: "#3f3f46"
  };
  const pillStyles = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#d8b4fe",
      color: "#6b21a8"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#5eead4",
      color: "#115e59"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#86efac",
      color: "#166534"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#93c5fd",
      color: "#1e40af"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fca5a5",
      color: "#991b1b"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fdba74",
      color: "#9a3412"
    }
  };
  const getPillStyle = name => ({
    ...defaultPillStyle,
    ...pillStyles[name] || ({})
  });
  return <div className="not-prose my-4 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm dark:border-white/10 dark:bg-white/5">
      <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
        <span className="font-semibold text-zinc-700 dark:text-zinc-200">
          {label}:
        </span>
        {versions.map((v, i) => <span key={`${v.name}-${v.version}-${i}`} className="inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium" style={getPillStyle(v.name)}>
            <span>{v.name}</span>
            <span className="opacity-70">
              {v.version}
              {v.exact ? "" : "+"}
            </span>
          </span>)}
      </div>
    </div>;
};

Por padrão, o AppSignal tenta registrar o máximo possível de exceções (erros). Com [nossas integrações](/ruby/integrations) 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](/guides/filter-data/ignore-errors). 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.

<CodeGroup>
  ```ruby Ruby theme={null}
  begin
    user = Post.find(1)
  rescue RecordNotFound => e
    render :text => "Could not find post", :status => 404
  end
  ```
</CodeGroup>

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](https://blog.appsignal.com/blog/2016/10/18/ruby-magic-exceptions-primer.html)
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.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

Mais informações sobre `rescue_from` podem ser encontradas no guia do Rails sobre
[ActionController](https://guides.rubyonrails.org/action_controller_overview.html#rescue-from).

### 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`](#appsignalreport_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](#legacy-exception-handling).

## Appsignal.report\_error

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "4.0.0" }]} />

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`.

<CodeGroup>
  ```ruby Ruby theme={null}
  begin
    # Some code that raises an exception
  rescue => error
    Appsignal.report_error(error)
    puts "Exiting. An error occurred: #{error}"
    exit 1
  end
  ```
</CodeGroup>

### 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](/guides/tagging) e [Personalização de dados](/guides/custom-data) 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.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

### 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.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

### Reportar exceções que crasham um processo

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "4.0.0" }]} />

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

<CodeGroup>
  ```ruby Ruby theme={null}
  # some_script.rb
  require "appsignal"

  Appsignal.start

  raise "I will crash the process!"
  ```
</CodeGroup>

Para desabilitar essa funcionalidade, defina a [opção de configuração `enable_at_exit_reporter`](/ruby/configuration/options#option-enable_at_exit_reporter) como `false`.

### Processos Ruby de curta duração

Ao reportar exceções de [scripts Ruby](/ruby/instrumentation/background-jobs), [tarefas Rake](/ruby/integrations/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`](#appsignalreport_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`](#appsignal-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`](#appsignal-send_error):** Use `send_error` para reportar erros quando nenhuma transaction do AppSignal estiver ativa.

### Appsignal.set\_error

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "0.6.0" }]} />

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.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

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](/ruby/integrations) 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](/ruby/instrumentation/background-jobs).
Veja [`Appsignal.send_error`](#appsignal-send_error) para enviar erros sem uma transaction do AppSignal.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

### Appsignal.send\_error

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "0.6.0" }]} />

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](/ruby/integrations/rake) ou [scripts Ruby](/ruby/instrumentation/background-jobs) separados.

Isso é útil para instrumentação que não cria automaticamente transactions do AppSignal para perfilar, como nossas [integrações](/ruby/integrations).

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`.

<CodeGroup>
  ```ruby Ruby theme={null}
  begin
    # some code
  rescue => e
    Appsignal.send_error(e)
  end
  ```
</CodeGroup>

#### Adicionando metadados {/* id: appsignal-send_error-adding-metadata */}

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "2.9.0" }]} />

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.

<CodeGroup>
  ```ruby Ruby theme={null}
  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
  ```
</CodeGroup>

### Appsignal.listen\_for\_error

<Warning>
  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`](#appsignalreport_error).
</Warning>

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.

<CodeGroup>
  ```ruby Ruby theme={null}
  require "rake"
  require "appsignal"

  task :fail do
    Appsignal.listen_for_error do
      raise "I am an exception in a Rake task"
    end
  end
  ```
</CodeGroup>
