Skip to main content

Capturing Errors

Reflex provides multiple ways to capture errors in your Rails application.

Automatic Capture

Once installed, Reflex automatically captures:
  • Unhandled exceptions in controllers
  • Background job failures (Sidekiq, ActiveJob)
  • Rake task errors
No additional code required.

Manual Capture

Capture Exceptions

begin
  # risky operation
  process_payment(order)
rescue PaymentError => e
  BrainzLab::Reflex.capture(e)
  # handle gracefully
  flash[:error] = "Payment failed. Please try again."
end

Capture and Re-raise

If you want to capture but still raise:
begin
  risky_operation
rescue => e
  BrainzLab::Reflex.capture(e)
  raise
end

Capture Messages

For error-like events without an exception:
BrainzLab::Reflex.capture_message("User hit deprecated endpoint",
  level: :warning,
  extra: {
    endpoint: request.path,
    user_id: current_user.id
  }
)

Adding Context

User Context

BrainzLab::Reflex.capture(exception,
  user: {
    id: current_user.id,
    email: current_user.email,
    name: current_user.name,
    plan: current_user.plan
  }
)

Tags

Tags are indexed and searchable:
BrainzLab::Reflex.capture(exception,
  tags: {
    feature: "checkout",
    payment_provider: "stripe",
    environment: "production"
  }
)

Extra Data

Include any additional context:
BrainzLab::Reflex.capture(exception,
  extra: {
    order_id: order.id,
    cart_items: cart.items.count,
    attempted_amount: order.total
  }
)

Full Example

begin
  charge = Stripe::Charge.create(amount: order.total_cents)
rescue Stripe::CardError => e
  BrainzLab::Reflex.capture(e,
    user: { id: current_user.id, email: current_user.email },
    tags: { feature: "checkout", provider: "stripe" },
    extra: {
      order_id: order.id,
      amount: order.total,
      card_last4: params[:card_last4]
    }
  )
  flash[:error] = "Your card was declined."
  redirect_to checkout_path
end

Capture Levels

Set the severity level:
BrainzLab::Reflex.capture_message("Config missing", level: :warning)
BrainzLab::Reflex.capture_message("Service degraded", level: :error)
BrainzLab::Reflex.capture_message("Database failing", level: :fatal)
LevelUse Case
infoInformational events
warningSomething unexpected but not critical
errorErrors that need attention
fatalCritical system failures

Filtering Errors

Exclude Specific Exceptions

BrainzLab.configure do |config|
  config.reflex_excluded_exceptions = [
    'ActionController::RoutingError',
    'ActiveRecord::RecordNotFound'
  ]
end

Custom Filtering

BrainzLab.configure do |config|
  config.reflex_before_send = ->(event) {
    # Return nil to drop the event
    return nil if event.exception.message.include?("Bot detected")

    # Modify and return the event
    event.tags[:custom] = "value"
    event
  }
end

Background Jobs

Sidekiq

Errors in Sidekiq jobs are automatically captured with job context:
class PaymentJob
  include Sidekiq::Job

  def perform(order_id)
    order = Order.find(order_id)
    process_payment(order)  # Errors here are automatically reported
  end
end

ActiveJob

class ProcessOrderJob < ApplicationJob
  def perform(order)
    # Errors automatically captured
    order.process!
  end
end

Testing

In test environments, you can verify error capture:
RSpec.describe "Error handling" do
  it "captures payment errors" do
    expect(BrainzLab::Reflex).to receive(:capture)
      .with(kind_of(PaymentError))

    post "/checkout", params: { invalid: true }
  end
end