Project

General

Profile

Actions

Feature #19197

open

Add Exception#root_cause

Added by AMomchilov (Alexander Momchilov) almost 2 years ago. Updated over 1 year ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:111264]

Description

Description

I would like to add a #root_cause method to Exception.

It returns the last exception in linked-list of causality chain, that is, the original exception (whose own cause is nil).

Example

e = begin
    raise 'A' # This is the root cause
  rescue => a
    begin
      raise 'B'
    rescue => B
      begin
        raise 'C' # This is the outermost cause assigned to `e`
      rescue => c
        c
      end
    end
  end

# Here's what the structure looks like:
# C -> B -> A -> nil  
p(e)                   # => #<RuntimeError: C>
p(e.cause)             # => #<RuntimeError: B>
p(e.cause.cause)       # => #<RuntimeError: A>
p(e.cause.cause.cause) # => nil

# Here's the proposed API, showing that A is the root cause of e
p(e.root_cause)        # => #<RuntimeError: A>
# And that the root_cause has no further cause
p(e.root_cause.cause)  # => nil

Motivation

There are some kinds of exceptions that can occur all over the place (and might be wrapped by arbitrarily many middlemen), but are attributable to a singular global cause. For example, a database outage could raise exceptions in almost every line of business logic of an app that uses ActiveRecord models.

Fundamentally, you wouldn't want an error report for every one of these lines. You'd want to look at the root cause, and bucket all SQL-connection issues into a single report, regardless of where they surface.

Implementation

Draft PR: https://github.com/ruby/ruby/pull/6913

Actions

Also available in: Atom PDF

Like4
Like0Like0Like0Like0Like0Like0Like1Like0Like0