Reason #38 • February 7th, 2026

Minimal re-raise

Sometimes we may want to rescue an exception, handle it depending on the context, and then re-raise it if we decide we can't handle it after all. In Ruby, we can do that with bare raise without any arguments, which will re-raise the currently rescued exception.

Ruby
begin
  # Code that might raise an exception...
rescue SomeError => e
  if e.message.include?("specific condition")
    # Handle the error...
  else
    raise
  end
end
      
JavaScript
try {
  // Code that might throw an error...
} catch (e) {
  if (e instanceof SomeError && e.message.includes("specific condition")) {
    // Handle the error...
  } else {
    throw e;
  }
}
      

Yes, we kind of need to bring out the 🔎 to spot the difference here. I also wouldn't want to pretend that bare raise is very intuitive. Couldn't we just as well raise(e) to keep things explicit and obvious?

Well, sometimes we have to remember that Matz is also free to do whatever he feels like doing. And as long as the end result is me having to write less code to express the same thing, I'm not complaining.

Once you've seen it a few times, the raise without arguments idiom reads quite clearly as "re-raise the current exception". All's well that ends well!

Under the hood

Interestingly, raise isn't a keyword but is implemented as a method call, though it's implemented in C, which prevents us from inspecting its source code directly from IRB:

Ruby
method(:raise) # => #<Method: Object(Kernel)#raise(*)>
method(:raise).source_location # => nil
      

Essentially, the way bare raise finds the right error object to re-raise is by looking up the current $! global variable, which is set by the previous raise call.

For those of us who aren't fluent in C, it can be helpful to refer to the TruffleRuby source code instead, where raise is mostly implemented in its own dialect of Ruby:

TruffleRuby
def raise(exc = undefined, msg = undefined, ctx = nil, cause: undefined, **kwargs)
  # ...

  if Primitive.undefined?(exc) && $!
    exc = $!
  else
    # ...
  end
end
    

If you want to dig deeper, you can check out kernel.rb at the TruffleRuby GitHub repo. Or if you're brave enough, you can dig through the C implementation in MRI Ruby's eval.c file, starting from rb_f_raise.