Issue #10481 has been updated by Radan Skori.


Alex Boyd wrote:
> In addition to the above, here's another one: a block of code that could fail for reasons beyond your control, where you want to catch errors in a production environment and handle them as gracefully as possible while allowing them to pass through in development and test. In Rails, this could looklike:
> 
> ~~~ruby
> begin
>   ...critical code here...
> rescue SomeError if Rails.env.production?
>   ...try to recover as best we can...
> end
> ~~~

It seems to me that this is not a very good example. From a high level perspective there are two decisions to be made about an exception:
1. Deciding whether to raise or not to raise the exception
and
2. Deciding how to handle the exception

Raising the exception only in production clearly falls within "should I raise?" decision but here it is being performed as part of "how will I handle it?" decision. It seems to me that this decision should be done by the codethat is doing the raising. If I look at the place in code where raising ishappening I don't want to have to look for all the catch clauses to see that it will effectively not be raised at all in development.


I also agree with Tsuyoshi that error messages should be only for formatting. Instead, a child exception should have been raised.

That leaves the error_code based examples. That looks like it could be a legitimate use case but it seems to me it would be just as readable, if not more, as a case statement inside the rescue block. 

The feature it self looks very cool but looking at the code bases I'm working on I can't really see places where using it would be a better long term solution than refactoring the code that is doing the raising.

----------------------------------------
Feature #10481: Add "if" and "unless" clauses to rescue statements
https://bugs.ruby-lang.org/issues/10481#change-51092

* Author: Alex Boyd
* Status: Assigned
* Priority: Normal
* Assignee: Yukihiro Matsumoto
----------------------------------------
I'd like to propose a syntax change: allow boolean "if" and "unless" clauses to follow a rescue statement.

Consider the following:

~~~ruby
begin
  ...
rescue SomeError => e
  if e.error_code == 1
    ...handle error...
  else
    raise
  end
end
~~~

This is a fairly common way of dealing with exceptions where some conditionabove and beyond the exception's type determines whether the exception should be rescued. It's verbose, though, and it's not obvious at first glance exactly what conditions are being rescued, especially if "...handle error..." is more than a few lines long. I propose that the following be allowed:

~~~ruby
begin
  ...
rescue SomeError => e if e.error_code == 1
  ...handle error...
end
~~~

"unless" would, of course, be allowed as well:

~~~ruby
begin
  ...
rescue SomeError => e unless e.error_code == 2
  ...handle error...
end
~~~

A rescue statement whose boolean condition failed would be treated the sameas if the exception being raised didn't match the exception being rescued,and move on to the next rescue statement:

~~~ruby
begin
  ...
rescue SomeError => e if e.error_code == 1
  ...handle error code 1...
rescue SomeError => e if e.error_code == 2
  ...handle error code 2...
end
~~~

And finally, catch-all rescue statements would be allowed as well:

~~~ruby
begin
  ...
rescue => e if e.message == "some error"
  ...handle error...
end
~~~


---Files--------------------------------
rescue-conditions.diff (6.76 KB)
rescue-conditions.diff (6.57 KB)
smime.p7s (4.78 KB)


-- 
https://bugs.ruby-lang.org/