[#105450] [Ruby master Feature#18228] Add a `timeout` option to `IO.copy_stream` — "byroot (Jean Boussier)" <noreply@...>
SXNzdWUgIzE4MjI4IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGJ5cm9vdCAoSmVhbiBCb3Vzc2llciku
11 messages
2021/09/27
[ruby-core:105125] [Ruby master Feature#18145] Rescue by nested exception
From:
"svoop (Sven Schwyn)" <noreply@...>
Date:
2021-09-02 22:18:12 UTC
List:
ruby-core #105125
Issue #18145 has been reported by svoop (Sven Schwyn).
----------------------------------------
Feature #18145: Rescue by nested exception
https://bugs.ruby-lang.org/issues/18145
* Author: svoop (Sven Schwyn)
* Status: Open
* Priority: Normal
----------------------------------------
The introduction of `Exception#cause` helps a lot when debugging nested errors.
Same goes for wrapped errors. I'm not really sure whether such wrapped errors are an advisable pattern to begin with, feel free to comment on this, but I've used it in a couple of vendored gems dealing with payment providers.
Here's some simplified code to illustrate. The `Payment` class deals with all the gory things such as authorization, coercion or API quirks. A simplified version might look like this:
```ruby
require 'rest_client'
module Provider
class FindError < StandardError; end
class Payment
attr_reader :id, :amount
private_class_method :new
def initialize(id, amount)
@id, @amount = id, amount
end
def self.find(id)
response = RestClient.get('https://api.provider.com/payments', params: { id: id })
body = JSON.parse(response.body)
new(id, body.fetch('amount'))
rescue
raise FindError
end
end
end
```
You can easily `rescue` from anything going wrong when loading a payment:
```ruby
begin
Provider::Payment.find(123)
rescue FindError
...
end
```
However, you might want to rescue differently for some specific causes (e.g. not found) but not for others (e.g. timeout):
```ruby
begin
Provider::Payment.find(123)
rescue FindError => error
if error.cause.instance_of? RestClient::NotFound
...
else
...
end
end
```
How about allowing to rescue by nested exception with a syntax like?
```ruby
begin
Provider::Payment.find(123)
rescue FindError & RestClient::NotFound
...
rescue FindError
...
end
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>