appsignal / appsignal-ruby

🟥 AppSignal for Ruby gem
https://www.appsignal.com/ruby
MIT License
183 stars 116 forks source link

Support nested exceptions #1009

Closed luismiramirez closed 11 months ago

luismiramirez commented 1 year ago

When an exception is manually wrapped, it's possible to know the original exception by calling #cause

TODO

jessevdp commented 1 year ago

For some context, imagine a piece of code like the following. (A nice functioning example using: https://pokeapi.co)

module PokeApi
  Error = Class.new(StandardError)

  class Client

    def pokemon(name:)
      get("api/v2/pokemon/#{name}").body
    end

    private

      def get(...)
        connection.get(...)
      rescue Faraday::Error
        raise Error
      end

      def connection
        Faraday. new("https://pokeapi.co/") do |faraday|
          faraday.response :json
          faraday.response :raise_error
        end
      end

  end
end

In my code I rely on error.cause for details, while still having the nice custom exceptions (with very minimal work).

poke_api = PokeApi::Client.new
begin
  poke_api.pokemon(name: "definetly-invalid")
rescue PokeApi::Error => error
  puts error.cause.inspect
end

But Appsignal will pick this up simply as PokeApi::Error with no additional info.

luismiramirez commented 1 year ago

Hi there!

But Appsignal will pick this up simply as PokeApi::Error with no additional info.

We still need to think about the solution. To me, the two main concerns are:

@jessevdp as a nested error user? Which backtrace is the one you consider the most valuable?

jessevdp commented 1 year ago

I think the backtrace of the top-level error is still very important. The errors I'm wrapping are usually 3rd party libs so their backtrace is usually not as important. (Similar to "show application backtrace" vs "show full backtrace" buttons in Appsignal currently.)

Perhaps in ideal solution would be something like:

MyCustomException: <message>
...
backtrace
...

Caused by:
AnotherException: <message>
...
backtrace
...

This is definitely a type of format I've seen before.

I suppose the nesting is never actually infinite. So showing causes as far down as they'll go seems like the way to go. But of course I haven't done my research into all the edge cases that would uncover.

(I mean you might technically be able to code this into a loop, where 2 exceptions point at each other as their cause, but that shouldn't happen naturally, and could probably be detected)

jessevdp commented 1 year ago

Aside: for now I've used a bit of custom_data to uncover 1 level of error.cause. This isn't fully ideal but it surfaces just enough information for my current use. The backtraces as described above would be far better.

# somewhere in an initializer
class AppsignalNestedErrorEnricher
  def report(error, handled:, severity:, context:, source: nil)
    return if error.cause.nil?

    Appsignal::Transaction.current.set_sample_data(
      "custom_data",
      error_cause: {
        class: error.cause.class.name,
        message: error.cause.message,
      }
    )
  end
end

# This relies on Rails.error.report being run around the code.
Rails.error.subscribe(AppsignalNestedErrorEnricher.new)
# In ApplicationController
around_action do |_controller, action|
  # used by config/initializers/appsignal_nested_error_enricher.rb
  Rails.error.record(&action)
end
luismiramirez commented 1 year ago

This is very valuable info. Thank you very much @jessevdp

backlog-helper[bot] commented 12 months ago

This issue seems is labelled as a new feature. Our customers may want to be informed about these changes through a blog post announcement. An issue has been created in blog repo so we remember to publish a blog post about it.

If a blog post is not required, please add the [skip blogpost] tag next time, and close the created issue.

shairyar commented 12 months ago

https://app.intercom.com/a/inbox/yzor8gyw/inbox/admin/4356044/conversation/16410700272721 (private link)

backlog-helper[bot] commented 11 months ago

This is a message from the daily scheduled checks.

New issue guide | Backlog management | Rules | Feedback

jessevdp commented 11 months ago

I'd still love this feature 😁

unflxw commented 11 months ago

@jessevdp Well, I have good news for you...

ezgif-1-eedcea310d

Stay tuned! 📻

jessevdp commented 11 months ago

Hehe nice! 🥳

(I was just shushing the backlog-helper BTW 😁)

unflxw commented 11 months ago

Hi @jessevdp,

AppSignal for Ruby 3.5.0 was released yesterday, including support for error causes! See our changelog for details. 🎉