Current issues with having Errno
constants are:
Errno
exceptions can't be rescued specifically – that's either all or none.Errno#errno
is the only way to know the actual error type.The solution would be to use classes for errno errors to be able to differentiate them, in order to prevent the user to deal with integers.
Another solution if to have something like rescue ex if ex.something?
which will work really well with Errno. See #1124
So this might be just a duplicate of #1124
Actually is https://github.com/crystal-lang/crystal/pull/5003 "Change Errno into a hierarchy of OSError subclasses"
Thanks @oprypin for referencing your PR. I remembered there had been prior discussions, but couldn't find that specific one.
Currently, Errno
simply wraps the error reporting mechanism provided by libc and places it into an exception. It's a legacy and bad design and doesn't represent idiomatic Crystal. This is strictly different for stdlib APIs that don't depend on libc functions. They use to raise specific exception classes depending on the type of error. Regular users shouldn't have to care about errno and how an API is implemented. The user experience should be identical whether a stdlib API is implemented in pure Crystal or based on libc. And it should be portable (see #4835).
In my opinion, Errno
needs to go. No other language apart from ruby couples their exception hierarchy to a decades old hack around C not being able to return multiple values like this.
My vision for exceptions at 1.0
is that they not only are well-named and not platform-specific, but they contain accessible fields relating to the error. For example, a DNS lookup failure would have a getter for the name which was being resolved. A network connection failure would have the IPAddress
attached. errno
would still exist, as a property, for the few people who need it, but it'd largely be ignored because it's just not necessary.
There might be technical problems that need to be overcome to achieve a better API but they can be solved like any other.
Dunno if related but here's an example where IO::Error was caught but it allowed Errno to still propagate up through (accidentally): https://github.com/crystal-lang/crystal/issues/7136#issuecomment-550747522 FWIW :)
Most helpful comment
In my opinion,
Errno
needs to go. No other language apart from ruby couples their exception hierarchy to a decades old hack around C not being able to return multiple values like this.My vision for exceptions at
1.0
is that they not only are well-named and not platform-specific, but they contain accessible fields relating to the error. For example, a DNS lookup failure would have a getter for the name which was being resolved. A network connection failure would have theIPAddress
attached.errno
would still exist, as a property, for the few people who need it, but it'd largely be ignored because it's just not necessary.There might be technical problems that need to be overcome to achieve a better API but they can be solved like any other.