[m-rev.] IO error type
Volker Wysk
post at volker-wysk.de
Thu Aug 18 01:35:34 AEST 2022
Am Mittwoch, dem 17.08.2022 um 19:31 +1000 schrieb Julien Fischer:
>
> On Wed, 17 Aug 2022, Peter Wang wrote:
>
> > :- type system_error.
> >
> > :- func make_io_error(system_error, string) = io.error.
> >
> > :- pred get_system_error(io.error::in, system_error::out)
> > is semidet.
> >
> > That is, to introduce a backend/platform specific system_error
> > type,
> > and add a field for system_errors in the io.error type.
> > (It would still be possible to construct an io.error without a
> > system_error value.)
>
> That was my preferred approach as well, however on Windows there is
> samll wrinkle with this: some of the system error codes we return are
> *not* errno values but instead are system error codes (e.g. of the
> kind
> returned by GetLastError()). So at least on Windows, if you embed a
> raw
> system error in an io.error, you have the additional problem of
> having
> to know what kind of error code it is.
Going with the system_error approach, you should make system_error a
discriminated union of errno values and system error codes. But I think
the errno (name or value) should be made accessible even under Windows.
So the error handling can be made more platform independent.
So my idea would be to introcude *two* new fields in the io.error type:
an optional field for the errno and an optional new system_error field.
The system_error would be platform specific, whereas the errno field
would be POSIX specific. Something like this:
:- type errno == int.
:- type error ---> error(
..., % possibly some more error information
maybe(errno), % errno value
maybe(system_error) % platform specific parts
).
An additional, also optional field for a filename should also be added,
since this already is the de facto standard for POSIX error handling -
for the POSIX calls which operate on a file or directory.
> (This is not a problem with the existing code, since all error codes
> are turned into error messages fairly close to the point where they
> occur, and at those points we know what kind of error code it is.)
>
> Looking a bit closer: the calls to GetLastError() occur pretty much
> in the dir module, so maybe we can re-arrange how it handles errors
> to avoid that?
>
> > If we add your suggestion to allow converting an io.error to a
> > name,
> > we might have:
> >
> > % Returns a standard error name if the given error corresponds
> > % to a system error known to the Mercury system, e.g. "ENOENT"
> > % (or possibly the name of a Java or C# exception?).
>
> Given that C# and Java exceptions are usually arranged in a class
> hierarchy, which name would you return?
I don't know, but those exceptions should also be equiped with an errno
value, if possible. If this can be queried somehow (such as with the
errno variable immediately after the call?).
> > % Fails if the error is not a system error, or if the error is
> > % not one recognised by the Mercury system.
> > %
> > :- 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.
>
> My preference would be for the standard library to simply give access
> the the system error value and leave it for other system-specific
> libraries (e.g. the POSIX binding) to provide further facilities for
> examining it.
>
> Julien.
More information about the reviews
mailing list