View mode: basic / threaded / horizontal-split · Log in · Help
April 12, 2005
std.syserror could use a bit of tidying up
Looking at the std.syserror module, there are a few things about it that 
don't seem right:

(a) It is a class consisting of nothing but a single static function. 
Obviously whoever wrote it was thinking in Java (or maybe C#).

(b) At the moment it covers only Windows error codes.  It should be 
versioned for portability.  (Consequently, at the moment FileExceptions 
thrown on Linux are going to have the wrong messages....)

(c) It requires the error code to be passed in.  How about a function 
that actually interrogates the error code in the platform-appropriate 
way and then picks out the right message?


Two proposed solutions:

1. Deprecate the pointless Java idiom and use module-level functions. 
Implement the function aforementioned in (c).  Using an out parameter, 
the caller would be able to receive both the error code and the message.

Pro: Can be used in arbitrary exception classes.

Con: By itself, applications will not be able to tell at a glance 
whether an arbitrary exception class contains an error code.

2. Turn SysError into an exception class.  The constructor would take in 
an arbitrary string to use in the message (such as the filename as 
std.file is implemented, or an indication of what it failed to do), 
interrogate the system error code, and build the exception message from 
this information.  Exception classes such as FileException and 
StreamException would then derive from SysError.  (Would it make sense 
to call it SysException instead while we're at it?)

Pros: Would make exceptions involving system error codes easier to 
implement.  The SysError class would have the overall semantics of an 
exception containing a system error code; maybe some applications could 
make use of this.

Con: Classes that already derive from some other class cannot also 
derive from SysError.  Hence the idea doesn't get on well with the 
concept of using a base class to cover a certain category of errors that 
may or may not contain a system error code.

What do people think we should do?

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
April 12, 2005
Re: std.syserror could use a bit of tidying up
On Tue, 12 Apr 2005 11:13:05 +0100, Stewart Gordon <smjg_1998@yahoo.com>  
wrote:
> Looking at the std.syserror module, there are a few things about it that  
> don't seem right:
>
> (a) It is a class consisting of nothing but a single static function.  
> Obviously whoever wrote it was thinking in Java (or maybe C#).

Indeed. It does seem a bit redundant.. unless.. what if you want to  
construct it when the error occurs but save it for later? i.e. save both  
the error code and the resulting string.

> (b) At the moment it covers only Windows error codes.  It should be  
> versioned for portability.  (Consequently, at the moment FileExceptions  
> thrown on Linux are going to have the wrong messages....)

I have a version that calls strerror on Linux. I believe it works. (but  
have not tested it on a Linux machine)

> (c) It requires the error code to be passed in.  How about a function  
> that actually interrogates the error code in the platform-appropriate  
> way and then picks out the right message?

The problem I have with this idea is.. for example Socket error codes are  
returned by the WSAGetLastError function, normal error codes by  
GetLastError, both sets of codes can be passed to my version of syserror.d  
and it will generate the correct error message.

So, in any situation where the error code does not come directly from the  
GetLastError function (on windows) or errno (on linux) but can still have  
a message generated by the FormatMessage (on windows) and strerror (on  
linux) functions you're stuck.

> Two proposed solutions:
>
> 1. Deprecate the pointless Java idiom and use module-level functions.  
> Implement the function aforementioned in (c).  Using an out parameter,  
> the caller would be able to receive both the error code and the message.
>
> Pro: Can be used in arbitrary exception classes.
>
> Con: By itself, applications will not be able to tell at a glance  
> whether an arbitrary exception class contains an error code.

I don't like this, for reasons voiced above.

> 2. Turn SysError into an exception class.  The constructor would take in  
> an arbitrary string to use in the message (such as the filename as  
> std.file is implemented, or an indication of what it failed to do),  
> interrogate the system error code, and build the exception message from  
> this information.  Exception classes such as FileException and  
> StreamException would then derive from SysError.  (Would it make sense  
> to call it SysException instead while we're at it?)
>
> Pros: Would make exceptions involving system error codes easier to  
> implement.  The SysError class would have the overall semantics of an  
> exception containing a system error code; maybe some applications could  
> make use of this.
>
> Con: Classes that already derive from some other class cannot also  
> derive from SysError.  Hence the idea doesn't get on well with the  
> concept of using a base class to cover a certain category of errors that  
> may or may not contain a system error code.

But, if we combine this option with exception chaining (see Ben's post  
about this), we can throw an exception, and pass SysError as the 'cause'  
of that exception, right?

> What do people think we should do?

Option #2 with error chaining.

Attached is my (not perfect) version of syserror.d

Regan
April 12, 2005
Re: std.syserror could use a bit of tidying up
FYI the attached syserror.d is intended for "public domain".

On Tue, 12 Apr 2005 23:52:58 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> On Tue, 12 Apr 2005 11:13:05 +0100, Stewart Gordon <smjg_1998@yahoo.com>
> wrote:
>> Looking at the std.syserror module, there are a few things about it that
>> don't seem right:
>>
>> (a) It is a class consisting of nothing but a single static function.
>> Obviously whoever wrote it was thinking in Java (or maybe C#).
>
> Indeed. It does seem a bit redundant.. unless.. what if you want to
> construct it when the error occurs but save it for later? i.e. save both
> the error code and the resulting string.
>
>> (b) At the moment it covers only Windows error codes.  It should be
>> versioned for portability.  (Consequently, at the moment FileExceptions
>> thrown on Linux are going to have the wrong messages....)
>
> I have a version that calls strerror on Linux. I believe it works. (but
> have not tested it on a Linux machine)
>
>> (c) It requires the error code to be passed in.  How about a function
>> that actually interrogates the error code in the platform-appropriate
>> way and then picks out the right message?
>
> The problem I have with this idea is.. for example Socket error codes are
> returned by the WSAGetLastError function, normal error codes by
> GetLastError, both sets of codes can be passed to my version of  
> syserror.d
> and it will generate the correct error message.
>
> So, in any situation where the error code does not come directly from the
> GetLastError function (on windows) or errno (on linux) but can still have
> a message generated by the FormatMessage (on windows) and strerror (on
> linux) functions you're stuck.
>
>> Two proposed solutions:
>>
>> 1. Deprecate the pointless Java idiom and use module-level functions.
>> Implement the function aforementioned in (c).  Using an out parameter,
>> the caller would be able to receive both the error code and the message.
>>
>> Pro: Can be used in arbitrary exception classes.
>>
>> Con: By itself, applications will not be able to tell at a glance
>> whether an arbitrary exception class contains an error code.
>
> I don't like this, for reasons voiced above.
>
>> 2. Turn SysError into an exception class.  The constructor would take in
>> an arbitrary string to use in the message (such as the filename as
>> std.file is implemented, or an indication of what it failed to do),
>> interrogate the system error code, and build the exception message from
>> this information.  Exception classes such as FileException and
>> StreamException would then derive from SysError.  (Would it make sense
>> to call it SysException instead while we're at it?)
>>
>> Pros: Would make exceptions involving system error codes easier to
>> implement.  The SysError class would have the overall semantics of an
>> exception containing a system error code; maybe some applications could
>> make use of this.
>>
>> Con: Classes that already derive from some other class cannot also
>> derive from SysError.  Hence the idea doesn't get on well with the
>> concept of using a base class to cover a certain category of errors that
>> may or may not contain a system error code.
>
> But, if we combine this option with exception chaining (see Ben's post
> about this), we can throw an exception, and pass SysError as the 'cause'
> of that exception, right?
>
>> What do people think we should do?
>
> Option #2 with error chaining.
>
> Attached is my (not perfect) version of syserror.d
>
> Regan
April 12, 2005
Re: std.syserror could use a bit of tidying up
Regan Heath wrote:
> On Tue, 12 Apr 2005 11:13:05 +0100, Stewart Gordon
> <smjg_1998@yahoo.com>  wrote:
> 
>> Looking at the std.syserror module, there are a few things about 
>> it that don't seem right:
>> 
>> (a) It is a class consisting of nothing but a single static 
>> function.  Obviously whoever wrote it was thinking in Java (or 
>> maybe C#).
> 
> Indeed.  It does seem a bit redundant.. unless.. what if you want 
> to construct it when the error occurs but save it for later?  i.e. 
> save both the error code and the resulting string.

It certainly is redundant until this idea is implemented.  But if
you'd like to implement it, go ahead.  It leads towards option 2
anyway.

<snip>
>> (c) It requires the error code to be passed in.  How about a 
>> function that actually interrogates the error code in the 
>> platform-appropriate way and then picks out the right message?
> 
> The problem I have with this idea is.. for example Socket error 
> codes are returned by the WSAGetLastError function, normal error 
> codes by GetLastError, both sets of codes can be passed to my 
> version of syserror.d and it will generate the correct error 
> message.

Then we could hold on the two functions.  One is the msg function we
have now, and the other is the one that interrogates the error code
by the 'usual' means.  They could become two constructor forms when
option 2 is coded up.

> So, in any situation where the error code does not come directly 
> from the GetLastError function (on windows) or errno (on linux) but 
> can still have a message generated by the FormatMessage (on 
> windows) and strerror (on linux) functions you're stuck.
> 
>> Two proposed solutions:
>> 
>> 1.  Deprecate the pointless Java idiom and use module-level 
>> functions.  Implement the function aforementioned in (c).  Using 
>> an out parameter, the caller would be able to receive both the 
>> error code and the message.
>> 
>> Pro: Can be used in arbitrary exception classes.
>> 
>> Con: By itself, applications will not be able to tell at a glance 
>> whether an arbitrary exception class contains an error code.
> 
> I don't like this, for reasons voiced above.

Don't like what exactly?

<snip>
> 2.  Turn SysError into an exception class.  But, if we combine this 
> option with exception chaining (see Ben's post about this), we can 
> throw an exception, and pass SysError as the 'cause' of that 
> exception, right?
> 
>> What do people think we should do?
> 
> Option #2 with error chaining.
<snip>

I see....

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
April 12, 2005
Re: std.syserror could use a bit of tidying up
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message 
news:d3g6vh$28ob$1@digitaldaemon.com...
> Looking at the std.syserror module, there are a few things about it that 
> don't seem right:
>
> (a) It is a class consisting of nothing but a single static function. 
> Obviously whoever wrote it was thinking in Java (or maybe C#).

agreed

> (b) At the moment it covers only Windows error codes.  It should be 
> versioned for portability.  (Consequently, at the moment FileExceptions 
> thrown on Linux are going to have the wrong messages....)

agreed

> (c) It requires the error code to be passed in.  How about a function that 
> actually interrogates the error code in the platform-appropriate way and 
> then picks out the right message?
>
> Two proposed solutions:
>
> 1. Deprecate the pointless Java idiom and use module-level functions. 
> Implement the function aforementioned in (c).  Using an out parameter, the 
> caller would be able to receive both the error code and the message.
>
> 2. Turn SysError into an exception class.
> What do people think we should do?

I like option 2 except that it feels dangerous to tie the inheritance tree 
to platform-specific support of error codes or strings. Off the top of my 
head perhaps SysError needs to get merged with Exception (copied from my 
proposed Exception in a previous post):
class Exception {
   char[] msg;
   Object cause;
   this(char[] msg, Object cause = null);
   void print(); // print this exception and any causes
   char[] toString(); // string summarizes this exception
   bit hasSysCode(out int code);
   bit hasSysMsg(out char[] msg);
}
It would be useful to have both a platform-independent message in msg and a 
platform-dependent message (if any) in hasSysMsg. By default hasSysCode and 
hasSysMsg return false. I haven't thought too hard about supporting system 
codes and strings but it would be nice to do cleanly in the exception 
hierarchy somehow. I hope other people chime in with ideas, too.
April 12, 2005
Re: std.syserror could use a bit of tidying up
>> 2. Turn SysError into an exception class.
>
> But, if we combine this option with exception chaining (see Ben's post
> about this), we can throw an exception, and pass SysError as the 'cause'
> of that exception, right?

That might be pretty good. The SysError never gets thrown itself - it just 
gets carried around as the cause. I like that better than my reply to 
Stewart about adding some methods to Exception. It seems cleaner to have the 
smarts in SysError and add the methods there and attach it to the cause.
April 12, 2005
Re: std.syserror could use a bit of tidying up
Assimilating this thread I have produced the attached code.
Comments?

Regan
April 12, 2005
Re: std.syserror could use a bit of tidying up
"Regan Heath" <regan@netwin.co.nz> wrote in message 
news:opso43rwqc23k2f5@nrage.netwin.co.nz...
> Assimilating this thread I have produced the attached code.
> Comments?

Very nice! One question: did you subclass Error to get "the class that 
allows chaining" or for some other reason? I'm guessing you did for the 
chaining. If Error is merged with Exception and the Error class goes away 
what do you think of keeping the name SysError but subclassing Exception? I 
think the name SysError is ok since the OS functions are called GetLastError 
and strerror and errorCode etc etc.

So to summarize, user code would look something like:

version (Windows) {
 handle = SomeOSFunction(...);
 if (handle == INVALID_HANDLE_VALUE) {
   throw new SomeException("Something failed",new 
SysError(GetLastError()));
 }
} else {
 result = someOSFunction(...);
 if (result == error) {
   throw new SomeException("Something failed",new SysError(getErrno()));
 }
}
April 12, 2005
Re: std.syserror could use a bit of tidying up
On Tue, 12 Apr 2005 19:14:16 -0400, Ben Hinkle <ben.hinkle@gmail.com>  
wrote:
> "Regan Heath" <regan@netwin.co.nz> wrote in message
> news:opso43rwqc23k2f5@nrage.netwin.co.nz...
>> Assimilating this thread I have produced the attached code.
>> Comments?
>
> Very nice!

Thank you.

> One question: did you subclass Error to get "the class that
> allows chaining" or for some other reason? I'm guessing you did for the
> chaining.

Yes.

> If Error is merged with Exception and the Error class goes away
> what do you think of keeping the name SysError but subclassing Exception?

Sounds good.

> I think the name SysError is ok since the OS functions are called  
> GetLastError and strerror and errorCode etc etc.

Indeed. Or SystemError if people want something a little more verbose, I  
don't mind either myself.

> So to summarize, user code would look something like:
>
> version (Windows) {
>   handle = SomeOSFunction(...);
>   if (handle == INVALID_HANDLE_VALUE) {
>     throw new SomeException("Something failed",new
> SysError(GetLastError()));
>   }
> } else {
>   result = someOSFunction(...);
>   if (result == error) {
>     throw new SomeException("Something failed",new SysError(getErrno()));
>   }
> }

Exactly. It's maybe important to note that, for example, your average  
programmer might never need/see SysError itself as we will likely do  
things like:

try {
  BufferedFile f = new BufferedFile("a.txt",FileMode.In);
} catch (FileNotFound e) {
}

in Phobos, where FileNotFound is thrown by a line resembling:

throw new FileNotFound("Failed to read("~file~")",new  
SysError(GetLastError()));

Regan
April 13, 2005
Re: std.syserror could use a bit of tidying up
> try {
>   BufferedFile f = new BufferedFile("a.txt",FileMode.In);
> } catch (FileNotFound e) {
> }
>
> in Phobos, where FileNotFound is thrown by a line resembling:
>
> throw new FileNotFound("Failed to read("~file~")",new 
> SysError(GetLastError()));

Agreed. I've always been annoyed that the exceptions in std.stream don't 
capture the full error information from the system. Currently I think if a 
file stream ctor fails it says something like "Could not create or open 
file" and maybe it doesn't even give the file name. It would be very nice to 
give as much info as possible.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home