[m-rev.] IO error type
Peter Wang
novalazy at gmail.com
Thu Aug 18 17:24:20 AEST 2022
On Thu, 18 Aug 2022 14:11:05 +1000 Julien Fischer <jfischer at opturion.com> wrote:
>
> My proposal is as follows:
>
> 1. We keep the definition of the type system_error/0 as it is, namely:
>
> :- type system_error.
> :- pragma foreign_type(c, system_error, "MR_Integer").
> :- pragma foreign_type("C#", system_error, "System.Exception").
> :- pragma foreign_type(java, system_error, "java.lang.Exception").
>
> (Actually, the Java version probably ought to be java.lang.Throwable,
> but that's a different matter.)
>
> 2. We export system_error/0 in the documented interface of the io module
> and also document what its foreign representation is for each backend.
>
> 3. We redefine io.error to be like the following:
>
> :- type io.error
> ---> io_error_string(string) % for use by make_io_error/1.
> ; io_error_errno(string, system_error)
> ; io_error_win_error(string, system_error)
> ; io_error_csharp_java_error(string, system_error).
>
> (At the point we construct these values we will know whether an "int"
> error is an errno or Windows error code.)
>
> Since io.error now contains the system error we could also omit the
> string in the latter threee cases and only construct it if the user
> requests it.
>
Ok.
> 4. We can add various semidet functions for classifying and retrieving
> the system_error value, e.g.
>
> :- pred io.get_errno_error(io.error::in, system_error::out)
> is semidet.
> :- pred io.get_windows_error(io.error::in, system_error::out)
> is semidet.
>
> etc. etc. This provides a mechanism for third-party libraries to get
> the raw error code / exception (and know what kind of error code it is).
>
Ok.
> 5. We also add the functions you listed below
>
> >>> :- pred get_error_name(io.error::in, string::out)
> >>> is semidet.
> >>>
> >>> % As above, but takes a system_error instead.
> >>> %
> >>> :- pred get_system_error_name(system_error::in, string::out)
> >>> is semidet.
>
> except that the signature of the latter one would be:
>
> :- pred get_system_error_name(io.error::in, string::out)
> is semidet.
Right, if a system_error could be value from multiple sets of errors
then we can't have a predicate that converts an system_error (only) to a
string.
> (I hope there's a way of getting Windows error code name, that doesn't
> involve switching over all 5000 or so Windows error codes; perhaps
> FormatMessage can do that?)
>
I couldn't find one :(
The MinGW-w64 winerror.h defines ~1765 ERROR_* constants, which should
be far beyond what we need to recognise (practically). Both the switch
for the POSIX and Windows errors would be auto-generated, so it's just a
matter of code size.
> I would prefer not too push large chunks of OS-specific stuff into the
> standard library: that doesn't improve portability, it just means
> programmers have to program around the bits their system doesn't
> support. Examining the different kinds of errors produced by system
> calls is intrinsically a OS-specific thing. The standard library can
> only paper over the difference so far.
I agree with not including too much OS specific functionality in the
standard library. But we provide basic I/O like opening files, deleting
files, etc. and, as it is, the functionality seems incomplete.
Peter
More information about the reviews
mailing list