Build Status

Nesty

Now, when you rescue an error and then re-raise your own, you don't have to lose track of what actually occured, you can keep/nest the old error in your own and the stacktrace will reflect the cause of the original error.

Why Use It?

When you use libraries that raise their own errors, it's not a good idea to allow these errors to bubble up through your app/library. Clients of your app/library should only have to deal with errors that belong to your app and not ones that come from libraries that your app is using. To achieve this without nested exception support, you would need to rescue the error that come from external libraries and then raise your own errors in their place. Of course, when you do this you lose the information from the original error. With nested exception support you no longer have to lose this information which is very handy.

Installation

Add this line to your application's Gemfile:

gem 'nesty'

And then execute:

$ bundle

Or install it yourself as:

$ gem install nesty

Usage

Super simple, create your own error class just like normal, but include a module in it:

class HappyError < StandardError
  include Nesty::NestedError
end

Alternatively rather than inheriting from StandardError do this:

HappyError = Class.new(Nesty::NestedStandardError)

Instances of HappyError will now support nesting another error inside.

Here is how we can use this:

begin
  raise StandardError.new
rescue => e
  raise HappyError.new("hello", e)
end

That was the explicit way, you raise another error and pass in the error you rescued, but you can also do this:

begin
  raise StandardError.new
rescue => e
  raise HappyError.new
end

This is the implicit way, the HappyError instance will still nest the StandardError that was rescued.

You can of course go deeper and keep rescuing and raising your own errors. As long as you raise with instances that support nesting (e.g. ones that include Nesty::NestedError or inherit from Nesty::NestedStandardError), the stacktrace will include all the nested exception messages.

What The Stacktrace Will Look Like?

It's probably a good idea to keep the stacktrace as close to a normal one as possible and in this case it actually will look very similar to a normal stacktrace. The only difference is that the error messages for all the nested errors will be included in the stacktrace (as opposed to just the message for the outer error).

Let's illustrate with an example.

We have 3 errors, A, B and C all nested in each other (A is nested in B and B is nested in C). They have the following messages and backtrace arrays:

A - message: 'a', backtrace: ['2', '1']
B - message: 'b', backtrace: ['4', '3', '2', '1']
C - message: 'c', backtrace: ['6', '5', '4', '3', '2', '1']

If C was not nested and we allowed it to bubble up so that it gets dumped to standard output, we would see something like the following:

c
6
5
4
3
2
1

But, with out nested errors we would see the following:

c
6
5
4: b
3
2: a
1

Since a stacktrace for a nested error is always a subset of the stacktrace of the enclosing error, all we need to do is add the messages for each of our nested errors in the appropriate place in the stacktrace. Simple, but handy.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request


建立状态

Nesty

现在,当您解决错误,然后重新提出自己的错误时,您不必失去实际发生的情况,您可以保留/嵌套旧错误,并且堆栈跟踪将反映原因原始错误。

为什么用它?

当您使用引发自身错误的库时,通过应用程序/库启动这些错误并不是一个好主意。你的应用程序/库的客户端应该只处理属于你的应用程序的错误,而不是应用程序使用的库的错误。为了实现这一点,没有嵌套的异常支持,你需要拯救外部库中的错误,然后在自己的位置提出自己的错误。当然,当你这样做时,你会丢失原始错误的信息。使用嵌套异常支持,您不再需要丢失非常方便的信息。

安装

将此行添加到应用程序的Gemfile中:

gem 'nesty'

然后执行:

$ bundle

或者自己安装:

$ gem install nesty

用法

超级简单,像普通人一样创建自己的错误类,但在其中包含一个模块:

class HappyError < StandardError
  include Nesty::NestedError
end

而不是继承 StandardError ,请执行以下操作:

HappyError = Class.new(Nesty::NestedStandardError)

HappyError 的实例现在将支持在其中嵌套另一个错误。

这是我们如何使用这个:

begin
  raise StandardError.new
rescue => e
  raise HappyError.new("hello", e)
end
这是明确的方式,你提出另一个错误,并传递你救出的错误,但你也可以这样做:

begin
  raise StandardError.new
rescue => e
  raise HappyError.new
end

这是隐式的方式, HappyError 实例仍然会嵌套被救出的 StandardError

你当然可以进一步深入,不断的拯救和提高你自己的错误。只要你使用支持嵌套的实例(例如包含 Nesty :: NestedError 或继承自 Nesty :: NestedStandardError )的实例,堆栈跟踪将包括所有嵌套异常消息。

Stacktrace看起来像什么?

保持堆栈跟踪尽可能接近正常情况可能是个好主意,在这种情况下,它实际上看起来与普通堆栈跟踪非常相似。唯一的区别是,所有嵌套错误的错误消息都将包含在堆栈跟踪中(而不仅仅是外部错误的消息)。

我们以一个例子来说明。

我们有3个错误,A,B和C都嵌套在一起(A嵌套在B中,B嵌套在C中)。它们具有以下消息和回溯数组:

A - message: 'a', backtrace: ['2', '1']
B - message: 'b', backtrace: ['4', '3', '2', '1']
C - message: 'c', backtrace: ['6', '5', '4', '3', '2', '1']

如果C没有被嵌套,我们允许它冒泡,以便它被转储到标准输出,我们将看到如下所示:

c
6
5
4
3
2
1

但是,出于嵌套错误,我们会看到以下内容:

c
6
5
4: b
3
2: a
1

由于嵌套错误的堆栈跟踪始终是包含错误的堆栈跟踪的子集,所以我们需要做的是将每个嵌套错误的消息添加到堆栈跟踪中的适当位置。简单,但方便。

贡献

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request




相关问题推荐