For the complete documentation index, see llms.txt. This page is also available as Markdown.

Callbacks

Callbacks are hooks that allow you to run custom code at specific points during service and step execution. They're perfect for logging, benchmarking, auditing, and other cross-cutting concerns.

TL;DR

  • Define callbacks using DSL methods like before_service_run, after_step_run, etc.

  • Use symbols (method names) or procs/lambdas

  • Callbacks are inherited from parent classes

  • Around callbacks wrap execution and must yield

class User::Charge < ApplicationService
  before_service_run :log_start
  after_service_run :log_end
  on_service_failure :notify_admin

  around_step_run :benchmark_step

  step :authorize
  step :charge

  private

  def log_start(service)
    Rails.logger.info "Starting #{service.class.name}"
  end

  def log_end(service)
    Rails.logger.info "Finished #{service.class.name}"
  end

  def notify_admin(service)
    AdminMailer.service_failed(service).deliver_later
  end

  def benchmark_step(service, step_name)
    start = Time.current
    yield
    duration = Time.current - start
    Rails.logger.info "Step #{step_name} took #{duration}s"
  end
end

Available Callbacks

Service Callbacks

Callback
When it runs
Arguments

before_service_run

Before the service starts executing steps

(service)

after_service_run

After the service completes (success or failure)

(service)

around_service_run

Wraps the entire service execution

(service, &block)

on_service_success

After service completes without errors

(service)

on_service_failure

After service completes with errors

(service)

Step Callbacks

Callback
When it runs
Arguments

before_step_run

Before each step executes

(service, step_name)

after_step_run

After each step completes (success or failure)

(service, step_name)

around_step_run

Wraps each step execution

(service, step_name, &block)

on_step_success

After step completes without errors

(service, step_name)

on_step_failure

When step produces errors

(service, step_name)

on_step_crash

When step raises an exception

(service, step_name, exception)

Note the difference between on_step_failure and on_step_crash:

  • on_step_failure is called when a step adds errors (similar to on_service_failure)

  • on_step_crash is called when a step raises an exception

When a step crashes (raises an exception), after_step_run is NOT called.

Defining Callbacks

Using Symbols (Method Names)

The most common way to define callbacks is using symbols that reference instance methods:

Using Procs/Lambdas

For simple callbacks, you can use inline procs:

Around Callbacks

Around callbacks wrap execution and must call yield to continue:

Around Callbacks with Procs

When using procs for around callbacks, the block is passed as the last argument:

Multiple Callbacks

You can define multiple callbacks of the same type. They execute in the order they're defined:

Multiple Around Callbacks

Multiple around callbacks are nested, with the first one wrapping the second:

Callback Inheritance

Callbacks are inherited from parent classes. Child class callbacks run after parent callbacks:

Deep Inheritance

Callbacks accumulate through the inheritance chain:

Execution Order

Service Callbacks Order

Step Callbacks Order (for each step)

Normal execution (no exception):

Exception during step:

Use Cases

Logging

Benchmarking

Error Tracking

Audit Trail

Database Instrumentation

What's Next?

Learn about testing your services, including how to test callbacks.

Next: Testing

Last updated