---
title: "Ruby 2.5 adds Exception#full_message method"
description:
  "Ruby 2.5 has added Exception#full_message method to retrieve a string
  expression of an exception, formatted in the same way with that Ruby prints an
  uncaught exception out."
canonical_url: "https://www.bigbinary.com/blog/ruby-2-5-adds-exception-full_message-method"
markdown_url: "https://www.bigbinary.com/blog/ruby-2-5-adds-exception-full_message-method.md"
---

# Ruby 2.5 adds Exception#full_message method

Ruby 2.5 has added Exception#full_message method to retrieve a string expression
of an exception, formatted in the same way with that Ruby prints an uncaught
exception out.

- Author: Vishal Telangre
- Published: March 13, 2018
- Categories: Ruby 2.5, Ruby

Before Ruby 2.5, if we want to log a caught exception, we would need to format
it ourselves.

```ruby
class AverageService
  attr_reader :numbers, :coerced_numbers

  def initialize(numbers)
    @numbers = numbers
    @coerced_numbers = coerce_numbers
  end

  def average
    sum / count
  end

  private

  def coerce_numbers
    numbers.map do |number|
      begin
        Float(number)
      rescue Exception => exception
        puts "#{exception.message} (#{exception.class})\n\t#{exception.backtrace.join("\n\t")}"
        puts "Coercing '#{number}' as 0.0\n\n"

        0.0
      end
    end
  end

  def sum
    coerced_numbers.map(&:to_f).sum
  end

  def count
    coerced_numbers.size.to_f
  end
end

average = AverageService.new(ARGV).average
puts "Average is: #{average}"
```

```ruby
$ RBENV_VERSION=2.4.0 ruby average_service.rb 5 4f 7 1s0
invalid value for Float(): "4f" (ArgumentError)
	average_service.rb:18:in `Float'
	average_service.rb:18:in `block in coerce_numbers'
	average_service.rb:16:in `map'
	average_service.rb:16:in `coerce_numbers'
	average_service.rb:6:in `initialize'
	average_service.rb:37:in `new'
	average_service.rb:37:in `<main>'

Coercing '4f' as 0.0

invalid value for Float(): "1s0" (ArgumentError)
	average_service.rb:18:in `Float'
	average_service.rb:18:in `block in coerce_numbers'
	average_service.rb:16:in `map'
	average_service.rb:16:in `coerce_numbers'
	average_service.rb:6:in `initialize'
	average_service.rb:37:in `new'
	average_service.rb:37:in `<main>'

Coercing '1s0' as 0.0

Average of [5.0, 0.0, 7.0, 0.0] is: 3.0
```

It was [proposed](https://bugs.ruby-lang.org/issues/14141) that there should be
a simple method to print the caught exception using the same format that ruby
uses while printing an uncaught exception.

Some of the proposed method names were `display`, `formatted`, `to_formatted_s`,
`long_message`, and `full_message`.

Matz [approved](https://bugs.ruby-lang.org/issues/14141#note-15) the
`Exception#full_message` method name.

In Ruby 2.5, we can re-write above example as follows.

```ruby
class AverageService
  attr_reader :numbers, :coerced_numbers

  def initialize(numbers)
    @numbers = numbers
    @coerced_numbers = coerce_numbers
  end

  def average
    sum / count
  end

  private

  def coerce_numbers
    numbers.map do |number|
      begin
        Float(number)
      rescue Exception => exception
        puts exception.full_message
        puts "Coercing '#{number}' as 0.0\n\n"

        0.0
      end
    end
  end

  def sum
    coerced_numbers.map(&:to_f).sum
  end

  def count
    coerced_numbers.size.to_f
  end
end

average = AverageService.new(ARGV).average
puts "Average is: #{average}"
```

```ruby
$ RBENV_VERSION=2.5.0 ruby average_service.rb 5 4f 7 1s0
Traceback (most recent call last):
	6: from average_service.rb:37:in `<main>'
	5: from average_service.rb:37:in `new'
	4: from average_service.rb:6:in `initialize'
	3: from average_service.rb:16:in `coerce_numbers'
	2: from average_service.rb:16:in `map'
	1: from average_service.rb:18:in `block in coerce_numbers'
average_service.rb:18:in `Float': invalid value for Float(): "4f" (ArgumentError)

Coercing '4f' as 0.0

Traceback (most recent call last):
	6: from average_service.rb:37:in `<main>'
	5: from average_service.rb:37:in `new'
	4: from average_service.rb:6:in `initialize'
	3: from average_service.rb:16:in `coerce_numbers'
	2: from average_service.rb:16:in `map'
	1: from average_service.rb:18:in `block in coerce_numbers'
average_service.rb:18:in `Float': invalid value for Float(): "1s0" (ArgumentError)

Coercing '1s0' as 0.0

Average of [5.0, 0.0, 7.0, 0.0] is: 3.0
```

Note that, Ruby 2.5 prints exception backtrace in reverse order if STDERR is
unchanged and is a TTY as discussed
[in our previous blog post](https://blog.bigbinary.com/2018/03/07/ruby-2-5-prints-backstrace-and-error-message-in-reverse-order.html).

## Links

- [Human page](https://www.bigbinary.com/blog/ruby-2-5-adds-exception-full_message-method)
