1 Informe de errores
El informe de errores de Rails proporciona una forma estándar de recopilar excepciones que ocurren en su aplicación y reportarlas a su servicio o ubicación preferida.
El informe de errores tiene como objetivo reemplazar el código de manejo de errores repetitivo como este:
begin
hacer_algo
rescue AlgoEstaRoto => error
MiServicioDeInformeDeErrores.notificar(error)
end
con una interfaz consistente:
Rails.error.handle(AlgoEstaRoto) do
hacer_algo
end
Rails envuelve todas las ejecuciones (como solicitudes HTTP, trabajos e invocaciones de rails runner
) en el informe de errores, por lo que cualquier error no manejado que se produzca en su aplicación se informará automáticamente a su servicio de informes de errores a través de sus suscriptores.
Esto significa que las bibliotecas de informes de errores de terceros ya no necesitan insertar un middleware de Rack ni hacer ningún parche para capturar excepciones no manejadas. Las bibliotecas que utilizan ActiveSupport también pueden utilizar esto para informar advertencias de forma no intrusiva que antes se habrían perdido en los registros.
No es obligatorio utilizar el informe de errores de Rails. Todas las demás formas de capturar errores siguen funcionando.
1.1 Suscripción al informe
Para utilizar el informe de errores, necesita un suscriptor. Un suscriptor es cualquier objeto con un método report
. Cuando ocurre un error en su aplicación o se informa manualmente, el informe de errores de Rails llamará a este método con el objeto de error y algunas opciones.
Algunas bibliotecas de informes de errores, como Sentry y Honeybadger, se registran automáticamente como suscriptores. Consulte la documentación de su proveedor para obtener más detalles.
También puede crear un suscriptor personalizado. Por ejemplo:
# 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
Después de definir la clase del suscriptor, regístrela llamando al método Rails.error.subscribe
:
Rails.error.subscribe(ErrorSubscriber.new)
Puede registrar tantos suscriptores como desee. Rails los llamará en orden, en el orden en que se registraron.
NOTA: El informe de errores de Rails siempre llamará a los suscriptores registrados, independientemente de su entorno. Sin embargo, muchos servicios de informes de errores solo informan errores en producción de forma predeterminada. Debe configurar y probar su configuración en todos los entornos según sea necesario.
1.2 Uso del informe de errores
Hay tres formas en las que puede utilizar el informe de errores:
1.2.1 Informar y omitir errores
Rails.error.handle
informará cualquier error que se produzca dentro del bloque. Luego omitirá el error y el resto de su código fuera del bloque continuará como de costumbre.
resultado = Rails.error.handle do
1 + '1' # genera TypeError
end
resultado # => nil
1 + 1 # Esto se ejecutará
Si no se produce ningún error en el bloque, Rails.error.handle
devolverá el resultado del bloque, de lo contrario devolverá nil
. Puede anular esto proporcionando un fallback
:
usuario = Rails.error.handle(fallback: -> { User.anonymous }) do
User.find_by(params[:id])
end
1.2.2 Informar y volver a generar errores
Rails.error.record
informará errores a todos los suscriptores registrados y luego volverá a generar el error, lo que significa que el resto de su código no se ejecutará.
Rails.error.record do
1 + '1' # genera TypeError
end
1 + 1 # Esto no se ejecutará
Si no se produce ningún error en el bloque, Rails.error.record
devolverá el resultado del bloque.
1.2.3 Informar errores manualmente
También puede informar errores manualmente llamando a Rails.error.report
:
begin
# código
rescue StandardError => e
Rails.error.report(e)
end
Cualquier opción que pase se pasará a los suscriptores de errores.
1.3 Opciones de informe de errores
Las 3 API de informe (#handle
, #record
y #report
) admiten las siguientes opciones, que luego se pasan a todos los suscriptores registrados:
handled
: unBoolean
para indicar si el error fue manejado. Esto se establece entrue
de forma predeterminada.#record
lo establece enfalse
.severity
: unSymbol
que describe la gravedad del error. Los valores esperados son::error
,:warning
y:info
.#handle
lo establece en:warning
, mientras que#record
lo establece en:error
.context
: unHash
para proporcionar más contexto sobre el error, como detalles de la solicitud o del usuario.source
: unaString
sobre la fuente del error. La fuente predeterminada es"application"
. Los errores informados por bibliotecas internas pueden establecer otras fuentes; por ejemplo, la biblioteca de caché de Redis puede usar"redis_cache_store.active_support"
. Su suscriptor puede utilizar la fuente para ignorar errores en los que no esté interesado.ruby Rails.error.handle(context: { user_id: user.id }, severity: :info) do # ... end
1.4 Filtrado por Clases de Error
Con Rails.error.handle
y Rails.error.record
, también puedes elegir reportar solo errores de ciertas clases. Por ejemplo:
Rails.error.handle(IOError) do
1 + '1' # genera TypeError
end
1 + 1 # Los TypeErrors no son IOError, por lo que esto *no* se ejecutará
Aquí, el TypeError
no será capturado por el reportero de errores de Rails. Solo se reportarán instancias de IOError
y sus descendientes. Cualquier otro error se generará normalmente.
1.5 Configuración de Contexto Global
Además de configurar el contexto a través de la opción context
, puedes usar la API #set_context
. Por ejemplo:
Rails.error.set_context(section: "checkout", user_id: @user.id)
Cualquier contexto configurado de esta manera se fusionará con la opción context
.
Rails.error.set_context(a: 1)
Rails.error.handle(context: { b: 2 }) { raise }
# El contexto reportado será: {:a=>1, :b=>2}
Rails.error.handle(context: { b: 3 }) { raise }
# El contexto reportado será: {:a=>1, :b=>3}
1.6 Para Bibliotecas
Las bibliotecas de reporte de errores pueden registrar sus suscriptores en un Railtie
:
module MySdk
class Railtie < ::Rails::Railtie
initializer "my_sdk.error_subscribe" do
Rails.error.subscribe(MyErrorSubscriber.new)
end
end
end
Si registras un suscriptor de errores, pero aún tienes otros mecanismos de errores como un middleware de Rack, es posible que los errores se reporten varias veces. Debes eliminar tus otros mecanismos o ajustar la funcionalidad de reporte para que omita reportar una excepción que ya haya visto antes.
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor, contribuye si encuentras algún error tipográfico o factual. Para empezar, puedes leer nuestra contribución a la documentación sección.
También puedes encontrar contenido incompleto o desactualizado. Por favor, añade cualquier documentación faltante para main. Asegúrate de revisar Edge Guides primero para verificar si los problemas ya están resueltos o no en la rama principal. Consulta las Directrices de las Guías de Ruby on Rails para el estilo y las convenciones.
Si por alguna razón encuentras algo que corregir pero no puedes solucionarlo tú mismo, por favor abre un problema.
Y por último, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.