[racket-dev] Safe errno access across platforms.
I'm not sure...
Providing error-code information is an appealing idea. Instead of
`exn:fail:errno', we'd probably add a `prop:exn:error-code' property
that is implemented by subtypes of `exn:fail:filesystem', etc. Also,
the value of the property would need to provide both a code and a
"kind" for the code, such as 'posix for a code from from `errno' or
'windows for a code from GetLastError(). The way that error codes are
currently included in the text of error messages could be leveraged to
get them into an exception structure without too many changes.
I'm not sure about `errno->symbol' and how to make it both portable and
general, though. I can imagine an `errno->symbol' that works with the
most common and standard error results, but I think there must be some
platform variation, to say nothing of Windows error code versus Posix
`errno' values. Does some other high-level language deal with error
codes in a good way that we could imitate?
Then again, I worry that dealing with error codes in a general way is a
lot of work for a feature that probably won't find much use. That is, I
actually disagree with your claim that "it is often desirable to
distinguish error causes with as fine a resolution as the platform
provides"; it seems fairly rare to me --- aside from including
information in error messages, which Racket already does.
We have mostly dealt with interesting error cases by making new
exception subtypes, such as `exn:fail:filesystem:exists'. It might be
that `exn:fail:filesystem:not-exists' is useful to add. If that's the
only immediate need, though, maybe we should just add that for now.
At Mon, 3 Dec 2012 14:37:36 -0800, Nathan wrote:
> Hello,
>
> I'm new to racket, and only mildly familiar with scheme, so I
> apologize if I'm missing important details.
>
> Whenever an error occurs related to a C interface which uses "errno"
> to signal the kind of error, I propose the associated racket exception
> should capture this errno value separately from the error message. I
> propose exposing the literal value and also a cross-platform way to
> determine the symbolic name for that value on the current platform.
>
> The reason is that it is often desirable to distinguish error causes
> with as fine a resolution as the platform provides. The specific
> example that lead me to this issue is that I want to read a file, but,
> in the case that the file is not present, return a default value. In
> any other case (such as incorrect permissions, or should the path
> refer to a directory instead of a file), I want the error to
> propagate. A work-around for my particular case is to check for the
> file's existence before opening it for reading, but notice that this
> introduces one more race-condition, so I prefer my original strategy.
> This is just a single case, and I expect in general it will be useful
> or necessary to distinguish errno values.
>
> I chatted with dyoo on the freenode irc channel and he suggested I
> send mail to this list, because this would be a backwards incompatible
> change.
>
> I'm not too familiar with racket, so there may be much better API
> designs, but my first idea was to add a new base exception struct
> along the lines of (struct exn:fail:errno exn:fail (errno)) and some
> separate module for translation with errno->symbol and symbol->errno.
> Maybe it's nicer to just include the symbol directly in the exception
> structure.
>
> There are a few implementation details I'd caution about:
>
> In general, "errno" may be a macro, so a simple ffi wrapper may not be
> cross-platform (according to the manpage). The value of errno is in
> thread-local storage, and I have no idea how that relates to racket
> thread safety.
>
> Including *only* the symbolic name of an errno would be a mistake,
> IMO, because I'm an anti-fan of abstractions hiding the truth. OTOH,
> I'm also a fan of abstractions and interfaces, so excluding the
> symbolic name is essential for writing clean cross-platform code.
>
>
> Regards,
> Nathan Wilcox
>
> ps: So far I'm really enjoying racket! The documentation is
> excellent; there's a debian package I can simply apt-get; and I've
> been playing with the custom language design features which are much
> nicer than I realized for scheme-likes. I had always thought the
> status quo was splicing with quasiquote so the syntax features are a
> wonderful surprise. Also, I'm very interested to explore the
> sandboxing features, but I haven't yet learned them in detail. I'm
> quite pleased they include time and memory constraints.
> _________________________
> Racket Developers list:
> http://lists.racket-lang.org/dev