Skip to content

Programatically set the backtrace_location on exception#1107

Open
Edouard-chin wants to merge 1 commit into
ruby-concurrency:masterfrom
Shopify:ec-caller-locations
Open

Programatically set the backtrace_location on exception#1107
Edouard-chin wants to merge 1 commit into
ruby-concurrency:masterfrom
Shopify:ec-caller-locations

Conversation

@Edouard-chin

@Edouard-chin Edouard-chin commented Jun 18, 2026

Copy link
Copy Markdown

Hello 👋 , thank you for maintaining this library ! I'd like to introduce a change to allow for exception to be consistent when either calling backtrace or backtrace_locations on a rejected Future.

Problem

When a Future is rejected, we set the backtrace with an array of string locations. This makes for some inconsistency because exception.backtrace_locations return nil but exception.backtrace return the backtrace.

I'd like to be able to programmatically set the backtrace_location as well. This would allow some libraries that depend on the backtrace_location to correcly detect the backtrace of an error.

Solution

Since Ruby 3.4, it's now possible to set the backtrace_locations programatically. The way do do it is to call set_backtrace but with an array of Thread::Backtrace::Location objects.

- ### Problem

  When a Future is rejected, we set the backtrace with an array of
  string locations. This makes for some inconsistency because
  `exception.backtrace_locations` return nil but `exception.backtrace`
  return the backtrace.

  I'd like to be able to programmatically set the backtrace_location
  as well. This would allow some libraries that depend on the
  backtrace_location to correcly detect the backtrace of an
  error.

  ### Solution

  Since Ruby 3.4, it's now possible to set the backtrace_locations
  programatically. The way do do it is to call `set_backtrace` but
  with an array of `Thread::Backtrace::Location` objects.

@eregon eregon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just needs one change

raise Concurrent::Error, 'it is not rejected' unless rejected?
raise ArgumentError unless args.size <= 1
reason = Array(internal_state.reason).flatten.compact
locations_supported = RUBY_VERSION >= '3.4'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it a constant like:

Suggested change
locations_supported = RUBY_VERSION >= '3.4'
SET_BACKTRACE_LOCATIONS_SUPPORTED = RUBY_VERSION >= '3.4'

I would prefer to feature-detect this but it's probably a bit messy (would cause an exception on older Ruby, not nice with -d) so this is fine enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants