[m-rev.] IO error type

Julien Fischer jfischer at opturion.com
Thu Aug 18 14:32:09 AEST 2022


Hi,

On Wed, 17 Aug 2022, Volker Wysk wrote:

> Am Mittwoch, dem 17.08.2022 um 19:31 +1000 schrieb Julien Fischer:

> 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.

See my response to Peter's mail. The caveat would be: the only time you
have an errno value on Windows is when you make a call to a function in
the C runtime library. It you call the Windows API directly, you get
a Windows error code, which is a separate set of things. I.e. the result
is not going to be as platfrom indepndent as you would like (and that's
without considering the non-C backends).

> 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.

I don't like that idea. Quite a lot of the predicates in the io module
take a filename as an argument, if they return an error there's no
question as to what the filename was.

For the predicates that throw exceptions on file stream errors (e.g.
most of those that write to streams), there is a case to made for adding
the stream name to the error. However, rather than throwing an io.error
I think we should define a separate exception type for use by those
operation that contains the stream name (or other identifying value)
together with the error codes.

>> (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?).

That isn't how error handling in Java or C# works. The only way to query
errno would be by using native code and that is something we want to
minimise or preferably avoid entirely.

Julien.


More information about the reviews mailing list