Issue #10481 has been updated by Brian Hempel.

File smime.p7s added

 You¡Çre right there may be some risk for anti-patterns, but from myexperience this example in the original proposal is practical:
 
 begin
   ...
 rescue => e if e.message == "some error"
   ...handle error...
 end
 
 Sometime code libraries forget to make a separate object for every error and you are forced to match on the error message. Right now, you have to write code like:
 
 begin
 ¡Ä
 rescue => e
   raise unless e.message =~ /card declined/i
   ¡Ähandle error¡Ä
 end
 
 Granted, the best solution is to fix the code library.
 
 Brian Hempel
 
 
 On Dec 4, 2014, at 11:25 AM, bruka <bruka / idatainc.com> wrote:
 
 > I'm trying to think of use cases for this, but every scenario I think of, leads towards anti-patterns and bad programming practices. Here is my 2 (3) cents:
 > 
 > Anti-pattern #1: Using rescue clauses as conditionals to direct program flow.
 > 
 > I use the 'raise if my_obj.not_as_expected?' style as well, but I alwaysmake sure that those statements are trivially simple, that they appear in obvious places, and that there is at most 1 rescue clause. I think even this style is an anti-pattern, but I tell myself that if the code is simple enough that it's ok.
 > 
 > Anti-pattern #2: Too many rescue clauses.
 > 
 > Things like:
 > 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
 > 
 > is a code smell to me. Indicative that the method is doing too many things and that perhaps has too much fan-out. Might be a  violation of the Law of Demeter, where the method knows the types of objects it is working with,the types of errors they throw, and the internal structure of those error objects.
 > 
 > Anti-pattern #3: Programming flow is more difficult to follow.
 > 
 > It reminds of conditionals at the end of loops e.g.
 > 
 > my_arr.each do |ele|
 > ...10 lines of code...
 > end if some_condition
 > 
 > You read the entire loop and at the end you realize that it only runs incertain cases. Similar with the conditional rescues. You're jumping back and forth in your method to try to figure out what happens when. Not fun.
 > 
 > Moreover, as another person noted, skipping the rescue clause can deprive you of valuable debugging information. Why not just send the error to another object to be processed:
 > 
 > rescue StandardError => ex
 >       MyErrorProcessor.handle( ex, self )
 > end
 > 
 > These are just opinions on software architecture and I have nothing to say about the technical implementation of this. I may just be overthinking it, but again I think you need to show some good real-world use cases.
 > 
 > On Thu, Dec 4, 2014 at 3:24 AM, <alex / opengroove.org> wrote:
 > Issue #10481 has been updated by Alex Boyd.
 > 
 > 
 > Any update on this? Is this just waiting for 2.2 to make it out the door?
 > 
 > ----------------------------------------
 > Feature #10481: Add "if" and "unless" clauses to rescue statements
 > https://bugs.ruby-lang.org/issues/10481#change-50283
 > 
 > * Author: Alex Boyd
 > * Status: Assigned
 > * Priority: Normal
 > * Assignee: Yukihiro Matsumoto
 > * Category:
 > * Target version:
 > ----------------------------------------
 > 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 condition above 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 same as 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)
 > 
 > 
 > --
 > https://bugs.ruby-lang.org/
 >

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

* Author: Alex Boyd
* Status: Assigned
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* Category: 
* Target version: 
----------------------------------------
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/