[#121791] [Ruby Bug#21298] `ObjectSpace.allocation_class_path` returns inconsistent results depending on `TracePoint` state — "mame (Yusuke Endoh) via ruby-core" <ruby-core@...>

Issue #21298 has been reported by mame (Yusuke Endoh).

6 messages 2025/05/01

[#121830] [Ruby Feature#21309] Can Thread::Mutex be Ractor shareable? — "osyoyu (Daisuke Aritomo) via ruby-core" <ruby-core@...>

Issue #21309 has been reported by osyoyu (Daisuke Aritomo).

11 messages 2025/05/05

[#121837] [Ruby Feature#21311] Namespace on read (revised) — "tagomoris (Satoshi Tagomori) via ruby-core" <ruby-core@...>

Issue #21311 has been reported by tagomoris (Satoshi Tagomori).

109 messages 2025/05/06

[#121941] [Ruby Bug#21315] Finalizers violate the `rb_ractor_confirm_belonging` assertion — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>

Issue #21315 has been reported by byroot (Jean Boussier).

8 messages 2025/05/09

[#121950] [Ruby Bug#21316] Namespaces leak with permanent names — "fxn (Xavier Noria) via ruby-core" <ruby-core@...>

Issue #21316 has been reported by fxn (Xavier Noria).

10 messages 2025/05/09

[#121956] [Ruby Bug#21321] Namespaces do not support extending mixins — "fxn (Xavier Noria) via ruby-core" <ruby-core@...>

Issue #21321 has been reported by fxn (Xavier Noria).

8 messages 2025/05/09

[#121973] [Ruby Bug#21322] Namespaces and builtin classes as arguments and return values — "fxn (Xavier Noria) via ruby-core" <ruby-core@...>

Issue #21322 has been reported by fxn (Xavier Noria).

8 messages 2025/05/10

[#122054] [Ruby Bug#21333] heap-use-after-free caused by rehash during update — "cyruscyliu (Qiang Liu) via ruby-core" <ruby-core@...>

Issue #21333 has been reported by cyruscyliu (Qiang Liu).

9 messages 2025/05/13

[#122086] [Ruby Bug#21337] Using `not` on the RHS of a logical operator becomes valid syntax with Prism — "koic (Koichi ITO) via ruby-core" <ruby-core@...>

Issue #21337 has been reported by koic (Koichi ITO).

7 messages 2025/05/14

[#122101] [Ruby Bug#21340] Bump autoconf version to properly handle C23 bool/stdbool defines — "christo (Chris Alberti) via ruby-core" <ruby-core@...>

Issue #21340 has been reported by christo (Chris Alberti).

12 messages 2025/05/14

[#122114] [Ruby Bug#21341] `Namespace is not a module (TypeError)` without enabling the namespace — "yahonda (Yasuo Honda) via ruby-core" <ruby-core@...>

Issue #21341 has been reported by yahonda (Yasuo Honda).

7 messages 2025/05/15

[#122121] [Ruby Bug#21342] Segfault: invalid keeping_mutexes when using Mutex in Thread then Fiber after GC — "maciej.mensfeld (Maciej Mensfeld) via ruby-core" <ruby-core@...>

Issue #21342 has been reported by maciej.mensfeld (Maciej Mensfeld).

11 messages 2025/05/15

[#122154] [Ruby Feature#21346] Introduce `String#ensure_suffix` — "matheusrich (Matheus Richard) via ruby-core" <ruby-core@...>

Issue #21346 has been reported by matheusrich (Matheus Richard).

21 messages 2025/05/16

[#122164] [Ruby Feature#21347] Add `open_timeout` as an overall timeout option for `Socket.tcp` — "shioimm (Misaki Shioi) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMzQ3IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHNoaW9pbW0gKE1pc2FraSBTaGlvaSku

9 messages 2025/05/17

[#122184] [Ruby Misc#21350] Bundled gems lack online documentation — "osyoyu (Daisuke Aritomo) via ruby-core" <ruby-core@...>

Issue #21350 has been reported by osyoyu (Daisuke Aritomo).

8 messages 2025/05/18

[#122218] [Ruby Bug#21357] Crash in Hash#merge! with ruby-dev in rubocop-rspec test suite — "Earlopain (Earlopain _) via ruby-core" <ruby-core@...>

Issue #21357 has been reported by Earlopain (Earlopain _).

7 messages 2025/05/21

[#122228] [Ruby Feature#21359] Introduce `Exception#cause=` for Post-Initialization Assignment — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMzU5IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGlvcXVhdGl4IChTYW11ZWwgV2lsbGlh

9 messages 2025/05/22

[#122242] [Ruby Feature#21365] Add `Namespace#eval` — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

Issue #21365 has been reported by tenderlovemaking (Aaron Patterson).

12 messages 2025/05/22

[#122258] [Ruby Misc#21367] Remove link to ruby-doc.org from www.ruby-lang.org/en/documentation/ — "p8 (Petrik de Heus) via ruby-core" <ruby-core@...>

Issue #21367 has been reported by p8 (Petrik de Heus).

11 messages 2025/05/23

[#122277] [Ruby Bug#21371] Proposal to Remove SPARC Architecture Support from Ruby — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMzcxIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGlvcXVhdGl4IChTYW11ZWwgV2lsbGlh

10 messages 2025/05/24

[#122343] [Ruby Misc#21385] Namespace: Suggesting a rename — "fxn (Xavier Noria) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMzg1IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGZ4biAoWGF2aWVyIE5vcmlhKS4NCg0K

32 messages 2025/05/30

[#122345] [Ruby Feature#21386] Introduce `Enumerable#join_map` — "matheusrich (Matheus Richard) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMzg2IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IG1hdGhldXNyaWNoIChNYXRoZXVzIFJp

12 messages 2025/05/30

[ruby-core:122104] [Ruby Feature#21279] Bare "rescue" should not rescue NameError

From: "Earlopain (Earlopain _) via ruby-core" <ruby-core@...>
Date: 2025-05-14 17:13:49 UTC
List: ruby-core #122104
Issue #21279 has been updated by Earlopain (Earlopain _).


I wondered looks in the real world (not really, I only ran against tests) so I wrote some code:

```rb
require "prism"
by_message = Hash.new(0)
by_location = Hash.new(0)

class Visitor < Prism::Visitor
  attr_reader :hit

  def initialize(lineno)
    super()
    @lineno = lineno
    @hit = false
  end

  def visit_rescue_node(node)
    if node.exceptions.empty? || node.exceptions.any? { it.is_a?(Prism::ConstantReadNode) && it.name == :StandardError }
      @hit = true if @lineno == node.keyword_loc.start_line
    end
  end

  def visit_rescue_modifier_node(node)
    @hit = true if @lineno == node.keyword_loc.start_line
  end
end

TracePoint.new(:rescue) do |tp|
  if tp.raised_exception.is_a?(NameError)
    visitor = Visitor.new(tp.lineno)
    Prism.parse_file(tp.path).value.accept(visitor)
    if visitor.hit
      by_message["#{tp.path}:#{tp.lineno} #{tp.raised_exception}"] += 1
      by_location["#{tp.path}:#{tp.lineno}"] += 1
    end
  end
end.enable

END {
  pp by_message
  puts "--------------------"
  pp by_location
}
```

You can put it into a test helper or something like that. I ran it over activerecord and unsurprisingly it found the code that @p8 linked: the rails activerecord test suite raises a `NameError` there 450 times with a bunch of different classes that don't respond to `to_i`.

Seemingly it only finds 4 places in `activerecord` with bare rescues, but then again like said previously you can't really say if that is representative of actual usage since I got this number with tests only (or my code above is buggy). I do also like the semantics of modifier rescue right now.

----------------------------------------
Feature #21279: Bare "rescue" should not rescue NameError
https://bugs.ruby-lang.org/issues/21279#change-113257

* Author: AMomchilov (Alexander Momchilov)
* Status: Open
----------------------------------------
# Abstract

Bare `rescue` keywords (either as a modifier like `foo rescue bar` or as clause of a `begin` block) should _not_ rescue `NameError` or `NoMethodError`.

This behaviour is unexpected and hides bugs.

## Background

Many Rubyists are surprised to learn that [`NameError`](https://docs.ruby-lang.org/en/master/NameError.html) is a subclass of [`StandardError`](https://docs.ruby-lang.org/en/master/StandardError.html), so it's caught whenever you use a "bare" `rescue` block. 

```ruby
begin
  DoesNotExist
rescue => e
  p e # => #<NameError: uninitialized constant DoesNotExist>
end
```

Similarly, [`NoMethodError`](https://docs.ruby-lang.org/en/master/NoMethodError.html) is also rescued, because it's a subclass of `NameError`.

```ruby
begin
  does_not_exist()
rescue => e
  p e # => #<NoMethodError: undefined method `does_not_exist' for main>
end
```

This is almost never expected behaviour. `NameError`/`NoMethodError` is usually the result of a typo in the Ruby source, that cannot be reasonably recovered from at runtime. It's a programming error just like a [`SyntaxError`](https://docs.ruby-lang.org/en/master/SyntaxError.html), which _isn't_ a `StandandError`.

## Proposal

No matter the solution, solving this problem will require a breaking change. Perhaps this could be part of Ruby 4?

The most obvious solution is to change the superclass of `NameError` from `StandardError` to `Exception` (or perhaps [`ScriptError`](https://docs.ruby-lang.org/en/master/ScriptError.html), similar to `SyntaxError`).

### Alternatives considered

If we want to avoid changing the inheritance hierarchy of standard library classes, we could instead change the semantics of bare `rescue` from "rescues any subtype of `StandardError`", to instead be "rescues any subtype of `StandardError` except `NameError` or its subtypes". This is worse in my opinion, as it complicates the semantics for no good reason.

## Use cases

<details><summary>fun example</summary>
The worst case I've seen of this came from a unit tesat like so:

```ruby
test "aborts if create_user returns error" do
  mock_user_action(data: {
    user: { id: 123, ... },
    errors: [{ code: "foo123" }]
  })

  ex = assert_raises(StandardError) do
    CreateUser.perform(123)
  end

  assert_match(/foo123/, ex.message)
end
```

This test passes, but not for the expected reason. It turns out that inside of the business logic of `CreateUser`, the error code data was accessed as a method call like `error.code`, rather than a key like `error[:code]`. This lead to:

```
NoMethodError (undefined method `code' for {:code=>"foo123"}:Hash)
```

The `NoMethodError` is a `StandardError`, and even more insidious, because `foo123` is part of the NoMethodError's default message, the `assert_match(/foo123/, ex.message)` also mathches!

The correct fix here would be to introduce a specific error like `UserCreationError` that can be rescued specifically, with a field like `code` that can be matched instead of the message. Regardless, this illustrates the kind of confusion that comes from `NoMethodError` being a `StandardError`.
</details>

# Discussion

It might be useful to distinguish between `NameError`s made in "static" code like `DoesNotExist` or `does_not_exist()`, versus those encountered dynamically via `Object.const_get(dynamic_value)` or `object.send(dynamic_value)`. In those metaprogramming cases, the error could be a consequence of bad runtime data, which is more recoverable than just some fundamental error with your Ruby code.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/


In This Thread