This is a feature request to add exception filters similar to C# 6.
begin
...
rescue Errno => ex if ex.errno == Errno::EPERM
rescue => ex if log(ex)
rescue
end
For the example I think I'd prefer #445 though.
What would be the semantic if an exception occurs inside the condition? Throw it to the caller? Or keep trying to the following rescues first?
@jhass the log() portion of the example isn't covered by #445.
You can do:
begin
...
rescue ex : Errno
if ex.errno == Errno::EPERM
# do something
else
raise ex
end
rescue ex
if log(ex)
# do something
else
raise ex
end
end
I know it's more typing, but you can do this right now without introducing features and thinking about corner cases like the one @bcardiff mentions.
Plus, my guess is that this kind of logic might be needed in 1% of the code, so it's not such a big deal.
On the other hand, the original snippet could be easily rewritten by the compiler to the expansion I've shown. But you won't be able to do:
begin
...
rescue ex : Errno if ex.errno == Errno::EPERM
# ...
rescue ex : Errno if ex.errno == Errno::EBADF
# ...
end
Or yes, but the compiler needs more logic to handle these cases. So I think it's better if we keep things simple here.
And neither @waj nor me think that we should expand all the Errno hierarchy into exceptions, it will just bloat things up for, again, a use case that will happen 1% of the time.
So if @waj agrees, I'll close this and #445.
@asterite Applications that deal with lots of files will need to rescue specific exceptions and to handle them differently, especially when dealing with files created by multiple users.
Your example for what can be done is NOT the same. You can use if statements if they are the same exception class but not if they are different. In order to rescue the example below you would need a single rescue statement with multiple if or case statements.
rescue Errno if condition 1
rescue Errno if condition 2
rescue SomeOtherException
rescue Exception if condition 3
end
Consider this request syntactic sugar for
rescue ex : Errno if ex.errno == Errno::EPERM
is equivalent to
rescue ex : Errno
if ex.errno == Errno::EPERM
...
else
CONTINUE_SEARCHING_EXCEPTIONS
end
As far as corner cases there isn't one.
@technorama After talking with @waj he told me that he thinks this might be a good idea and it shouldn't be that hard to implement, so we'll probably do it.
I think that we should deconstruct Errno into multiple exceptions. PEP 3151 is a document which approaches a similar issue in python, and is well worth a read. The resulting exception hierarchy isn't particularly large. Some of them like BlockingIOError and InterruptedError could likely be avoided in crystal.
Most helpful comment
I think that we should deconstruct
Errnointo multiple exceptions. PEP 3151 is a document which approaches a similar issue in python, and is well worth a read. The resulting exception hierarchy isn't particularly large. Some of them likeBlockingIOErrorandInterruptedErrorcould likely be avoided in crystal.