1 Relatório de Erros
O relatório de erros do Rails error reporter fornece uma maneira padrão de coletar exceções que ocorrem em sua aplicação e relatá-las para o serviço ou localização de sua preferência.
O relatório de erros tem como objetivo substituir o código de tratamento de erros repetitivo, como este:
begin
faça_algo
rescue AlgoEstáQuebrado => erro
MeuServiçoDeRelatórioDeErros.notificar(erro)
end
por uma interface consistente:
Rails.error.handle(AlgoEstáQuebrado) do
faça_algo
end
O Rails envolve todas as execuções (como requisições HTTP, jobs e invocações rails runner
) no relatório de erros, então quaisquer erros não tratados levantados em sua aplicação serão automaticamente relatados para o seu serviço de relatório de erros por meio de seus assinantes.
Isso significa que bibliotecas de relatório de erros de terceiros não precisam mais inserir um middleware Rack ou fazer qualquer monkey-patching para capturar exceções não tratadas. Bibliotecas que usam o ActiveSupport também podem usar isso para relatar avisos de forma não intrusiva que anteriormente seriam perdidos nos logs.
O uso do relatório de erros do Rails não é obrigatório. Todos os outros meios de capturar erros ainda funcionam.
1.1 Assinando o Relatório
Para usar o relatório de erros, você precisa de um assinante. Um assinante é qualquer objeto com um método report
. Quando ocorre um erro em sua aplicação ou é relatado manualmente, o relatório de erros do Rails chamará esse método com o objeto de erro e algumas opções.
Algumas bibliotecas de relatório de erros, como Sentry e Honeybadger, registram automaticamente um assinante para você. Consulte a documentação do seu provedor para obter mais detalhes.
Você também pode criar um assinante personalizado. Por exemplo:
# config/initializers/error_subscriber.rb
class ErrorSubscriber
def report(error, handled:, severity:, context:, source: nil)
MyErrorReportingService.report_error(error, context: context, handled: handled, level: severity)
end
end
Após definir a classe do assinante, registre-a chamando o método Rails.error.subscribe
:
Rails.error.subscribe(ErrorSubscriber.new)
Você pode registrar quantos assinantes desejar. O Rails os chamará em sequência, na ordem em que foram registrados.
NOTA: O relatório de erros do Rails sempre chamará os assinantes registrados, independentemente do seu ambiente. No entanto, muitos serviços de relatório de erros relatam apenas erros em produção por padrão. Você deve configurar e testar sua configuração em todos os ambientes conforme necessário.
1.2 Usando o Relatório de Erros
Existem três maneiras de usar o relatório de erros:
1.2.1 Relatando e Ignorando Erros
Rails.error.handle
irá relatar qualquer erro levantado dentro do bloco. Em seguida, ele irá ignorar o erro, e o restante do seu código fora do bloco continuará normalmente.
resultado = Rails.error.handle do
1 + '1' # levanta TypeError
end
resultado # => nil
1 + 1 # Isso será executado
Se nenhum erro for levantado no bloco, Rails.error.handle
retornará o resultado do bloco, caso contrário, retornará nil
. Você pode substituir isso fornecendo um fallback
:
usuário = Rails.error.handle(fallback: -> { User.anonymous }) do
User.find_by(params[:id])
end
1.2.2 Relatando e Levantando Novamente Erros
Rails.error.record
irá relatar erros para todos os assinantes registrados e, em seguida, levantará novamente o erro, o que significa que o restante do seu código não será executado.
Rails.error.record do
1 + '1' # levanta TypeError
end
1 + 1 # Isso não será executado
Se nenhum erro for levantado no bloco, Rails.error.record
retornará o resultado do bloco.
1.2.3 Relatando Erros Manualmente
Você também pode relatar erros manualmente chamando Rails.error.report
:
begin
# código
rescue StandardError => e
Rails.error.report(e)
end
Quaisquer opções que você passar serão repassadas aos assinantes de erros.
1.3 Opções de Relatório de Erros
As 3 APIs de relatório (#handle
, #record
e #report
) suportam as seguintes opções, que são então repassadas a todos os assinantes registrados:
handled
: umBoolean
para indicar se o erro foi tratado. Isso é definido comotrue
por padrão.#record
define isso comofalse
.severity
: umSymbol
que descreve a gravidade do erro. Os valores esperados são::error
,:warning
e:info
.#handle
define isso como:warning
, enquanto#record
define como:error
.context
: umHash
para fornecer mais contexto sobre o erro, como detalhes da requisição ou do usuário.source
: umaString
sobre a origem do erro. A origem padrão é"application"
. Erros relatados por bibliotecas internas podem definir outras origens; a biblioteca de cache Redis pode usar"redis_cache_store.active_support"
, por exemplo. Seu assinante pode usar a origem para ignorar erros que você não está interessado.ruby Rails.error.handle(context: { user_id: user.id }, severity: :info) do # ... end
1.4 Filtrando por Classes de Erro
Com Rails.error.handle
e Rails.error.record
, você também pode escolher reportar apenas erros de certas classes. Por exemplo:
Rails.error.handle(IOError) do
1 + '1' # gera TypeError
end
1 + 1 # TypeErrors não são IOErrors, então isso *não* será executado
Aqui, o TypeError
não será capturado pelo relator de erros do Rails. Apenas instâncias de IOError
e suas subclasses serão reportadas. Quaisquer outros erros serão lançados normalmente.
1.5 Definindo Contexto Globalmente
Além de definir o contexto através da opção context
, você pode usar a API #set_context
. Por exemplo:
Rails.error.set_context(section: "checkout", user_id: @user.id)
Qualquer contexto definido dessa maneira será mesclado com a opção context
.
Rails.error.set_context(a: 1)
Rails.error.handle(context: { b: 2 }) { raise }
# O contexto reportado será: {:a=>1, :b=>2}
Rails.error.handle(context: { b: 3 }) { raise }
# O contexto reportado será: {:a=>1, :b=>3}
1.6 Para Bibliotecas
Bibliotecas de relatório de erros podem registrar seus assinantes em um Railtie
:
module MySdk
class Railtie < ::Rails::Railtie
initializer "my_sdk.error_subscribe" do
Rails.error.subscribe(MyErrorSubscriber.new)
end
end
end
Se você registrar um assinante de erros, mas ainda tiver outros mecanismos de erro como um middleware Rack, você pode acabar com erros reportados várias vezes. Você deve remover seus outros mecanismos ou ajustar sua funcionalidade de relatório para pular a reportagem de uma exceção que já foi vista antes.
Feedback
Você é incentivado a ajudar a melhorar a qualidade deste guia.
Por favor, contribua se encontrar algum erro de digitação ou factual. Para começar, você pode ler nossa contribuição à documentação seção.
Você também pode encontrar conteúdo incompleto ou desatualizado. Por favor, adicione qualquer documentação ausente para o principal. Certifique-se de verificar Guias Edge primeiro para verificar se os problemas já foram corrigidos ou não no branch principal. Verifique as Diretrizes dos Guias do Ruby on Rails para estilo e convenções.
Se por algum motivo você encontrar algo para corrigir, mas não puder corrigi-lo você mesmo, por favor abra uma issue.
E por último, mas não menos importante, qualquer tipo de discussão sobre a documentação do Ruby on Rails é muito bem-vinda no Fórum oficial do Ruby on Rails.