Starting in Ruby 2.1, Ruby has Exception#cause which wraps the previous exception. This is typically referred to as a “wrapped exception.” Before Ruby 2.1, many projects would add a similar feature on a per-error basis. (If you happen to be on a version of Ruby before 2.1, there’s a backport gem which adds the feature… but please try to upgrade.)

This is now widely supported and defaults to $!. It should generally work in error reporting applications like Bugsnag, which renders the cause as “caused by” in the stacktrace tab.

Finally, unlike Java, which allows a nested exception’s cause to be set manually, Ruby only allows #cause to be $! at the time that the wrapping exception is raised. There is no #cause= or argument to Exception.new, and $! is a read-only variable. See the feature in Ruby’s Redmine for discussion about the reasoning. In effect, if you want to wrap an exception, you have to re-raise. This makes using any kind of Exception (StandardError, etc) as a value object more difficult. This includes use of Exception#cause in tests/specs or as a return value when you’d like to avoid the overhead of yet another raise.

Overall, Exception#cause is a great addition to base Ruby, but I would love an option like initCause in Java.

Charles Nutter said this:

Since the base #cause and $! logic made it in, perhaps we should call this bug closed as of 2.1 and add a new bug for additional ways to initialize the exception cause.

…but I’m not aware of any work to allow @cause to be manually set.