Project

General

Profile

Actions

Bug #16618

closed

Ensure called twice when raise in ensure

Added by davidsiaw (David Siaw) about 4 years ago. Updated almost 3 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-musl]
[ruby-core:97104]

Description

Under very specific circumstances (a return with code after it), a raise in an ensure block causes the ensure block to be called twice after rescuing in a rescue block above it.

Here is a very small reproduction case:

class ABC < StandardError; end

def meow
  return
  puts 'a'
rescue ABC
  puts 'rescue'
ensure
  puts 'ensure'
  raise ABC
end

meow

Causes the output

ensure
rescue
ensure
Traceback (most recent call last):
	1: from spec/meow.rb:13:in `<main>'
spec/meow.rb:10:in `meow': ABC (ABC)

However, if I remove the code below the return, the behavior is more reasonable:

class ABC < StandardError; end

def meow
  return
rescue ABC
  puts 'rescue'
ensure
  puts 'ensure'
  raise ABC
end

meow
ensure
Traceback (most recent call last):
	1: from spec/meow.rb:14:in `<main>'
spec/meow.rb:9:in `meow': ABC (ABC)

It does not seem to matter what code comes after return. It also does not seem to matter what code comes before the return, as long as the return is run. It could throw errors or it might not, but there seems to be a definite requirement that there is code after the return for this bug to occur.

Possibly related to #13930? I am not sure.


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #13930: Exception is caught in rescue above ensureClosedko1 (Koichi Sasada)Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0