Jump to page: 1 2
Thread overview
exception inheritance proposal
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Matthew
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Matthew
Apr 14, 2005
Regan Heath
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Regan Heath
Apr 14, 2005
Maxime Larose
Apr 14, 2005
Maxime Larose
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Ben Hinkle
Apr 14, 2005
Sean Kelly
Apr 14, 2005
Maxime Larose
Apr 14, 2005
Ben Hinkle
April 14, 2005
Over the past few days/weeks I've been going over the phobos exception usage. Below is my proposal for modifying the phobos exception class inheritance hierarchy (indenting indicates subclassing). I have no idea if Walter would actually accept anything close to this proposal, but I figure what the heck. See notes and questions at the end, too.

Object
   OutOfMemory
   AssertionFailure (was AssertError:Error)
      NoSwitchDefault (was SwitchError:Error)
   Exception
      ParamException (new)
         ParamNullException (new)
         ParamRangeException (new)
      IndexException (new)
         ArrayBoundsException (was ArrayBoundsError:Error)
      CollectionCopyException (new)
         ArrayCopyException (was Error in internal/arraycat.d)
      NotSupportedException (new)
      NotImplementedException (new)
      AddressException
      Base64Exception
         Base64CharException
      CastException (new)
         ArrayCastException (was Error in internal/arraycast.d)
      ConvException (was ConvError:Error)
         ConvOverflowException (was ConvOverflowError:ConvError)
      DateParseException (was DateParseError:Error)
      SystemError (see Regan's code posted on thread about std.syserror)
         FileException (was FileException:Exception)
         SocketException (was SocketException:Exception)
            SocketAcceptException
         HostException (was HostException:Exception)
         RegistryException (was RegistryException:Win32Exception)
         ExeModuleException (was ExeModuleException:Exception)
      FormatException (was FormatError:Error)
      ModuleCtorException (was ModuleCtorError:Exception)
      OpenRJException
         DatabaseException
         InvalidKeyException
         InvalidTypeException
      RegExpException (was RegExpError:Error)
      StreamException
         ReadException
         WriteException
         SeekException
         StreamFileException
            OpenException
      StringException
      ThreadException (was ThreadError:Error)
         OutOfThreadsException (new)
      URIException (was URIError:Error)
      UTFException (was UtfError:Error)
      ZipException
      ZlibException

Notes:
1. removed std.windows.registry.Win32Exception since it overlaps with
     SystemError for Windows
2. remove FooError aliases for std.stream exceptions
3. some exceptions might be thrown with SystemError causes
     (eg StreamFileException, ThreadException)
4. RegistryException is thrown once without a system error code
5. NotSupportedException will be a cause in
     - std.mmfile some thrown FileExceptions
     - std.stream in a StreamException that replaces a raw Exception
     - std.zip in several ZipExceptions
6. Backwards incompatibilities are limited (hopefully) to class names
involving Error
   and subclassing Error. The subclassing Error switches to Exception except
   for asserts and switch defaults don't subclass Exception in the new
scheme.
7. The array errors now subclass general reusable errors.

Exception is defined as
class Exception {
    char[] msg;
    Object cause; // new

    this(char[] msg, Object cause = null) { // new
        this.msg = msg;
        this.cause = cause; // new
    }

    void print() {
        printf("%.*s\n", msg);
        if (cause) cause.print(); // new
    }

    char[] toString() { return msg; }
}

For the definition of SystemError see Regan's post http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282

Questions:
1. what should the top few lines of the hierarchy look like?
2. should modules that currently reuse one exception create subclasses?
3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
     throw a raw Exception)
4. what is missing?


April 14, 2005
I don't much care about the leaf-side hierarchy, as I think the root is far more important. I'm a bit surprised to see that you've stuck with Object as the common base of the hierarchy. What is the reason behind that, given that the impression from the recent discussions has been, IME, that most wanted a change?

"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d3kkph$2t76$1@digitaldaemon.com...
> Over the past few days/weeks I've been going over the phobos exception usage. Below is my proposal for modifying the phobos exception class inheritance hierarchy (indenting indicates subclassing). I have no idea if Walter would actually accept anything close to this proposal, but I figure what the heck. See notes and questions at the end, too.
>
> Object
>   OutOfMemory
>   AssertionFailure (was AssertError:Error)
>      NoSwitchDefault (was SwitchError:Error)
>   Exception
>      ParamException (new)
>         ParamNullException (new)
>         ParamRangeException (new)
>      IndexException (new)
>         ArrayBoundsException (was ArrayBoundsError:Error)
>      CollectionCopyException (new)
>         ArrayCopyException (was Error in internal/arraycat.d)
>      NotSupportedException (new)
>      NotImplementedException (new)
>      AddressException
>      Base64Exception
>         Base64CharException
>      CastException (new)
>         ArrayCastException (was Error in internal/arraycast.d)
>      ConvException (was ConvError:Error)
>         ConvOverflowException (was ConvOverflowError:ConvError)
>      DateParseException (was DateParseError:Error)
>      SystemError (see Regan's code posted on thread about
> std.syserror)
>         FileException (was FileException:Exception)
>         SocketException (was SocketException:Exception)
>            SocketAcceptException
>         HostException (was HostException:Exception)
>         RegistryException (was RegistryException:Win32Exception)
>         ExeModuleException (was ExeModuleException:Exception)
>      FormatException (was FormatError:Error)
>      ModuleCtorException (was ModuleCtorError:Exception)
>      OpenRJException
>         DatabaseException
>         InvalidKeyException
>         InvalidTypeException
>      RegExpException (was RegExpError:Error)
>      StreamException
>         ReadException
>         WriteException
>         SeekException
>         StreamFileException
>            OpenException
>      StringException
>      ThreadException (was ThreadError:Error)
>         OutOfThreadsException (new)
>      URIException (was URIError:Error)
>      UTFException (was UtfError:Error)
>      ZipException
>      ZlibException
>
> Notes:
> 1. removed std.windows.registry.Win32Exception since it overlaps
> with
>     SystemError for Windows
> 2. remove FooError aliases for std.stream exceptions
> 3. some exceptions might be thrown with SystemError causes
>     (eg StreamFileException, ThreadException)
> 4. RegistryException is thrown once without a system error code
> 5. NotSupportedException will be a cause in
>     - std.mmfile some thrown FileExceptions
>     - std.stream in a StreamException that replaces a raw
> Exception
>     - std.zip in several ZipExceptions
> 6. Backwards incompatibilities are limited (hopefully) to class
> names involving Error
>   and subclassing Error. The subclassing Error switches to
> Exception except
>   for asserts and switch defaults don't subclass Exception in the
> new scheme.
> 7. The array errors now subclass general reusable errors.
>
> Exception is defined as
> class Exception {
>    char[] msg;
>    Object cause; // new
>
>    this(char[] msg, Object cause = null) { // new
>        this.msg = msg;
>        this.cause = cause; // new
>    }
>
>    void print() {
>        printf("%.*s\n", msg);
>        if (cause) cause.print(); // new
>    }
>
>    char[] toString() { return msg; }
> }
>
> For the definition of SystemError see Regan's post http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282
>
> Questions:
> 1. what should the top few lines of the hierarchy look like?
> 2. should modules that currently reuse one exception create
> subclasses?
> 3. when is it ok to just throw Exception? (ie - should
> internal/gc/gc.d
>     throw a raw Exception)
> 4. what is missing?
> 


April 14, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d3kos2$2vnh$1@digitaldaemon.com...
>I don't much care about the leaf-side hierarchy, as I think the root is far more important. I'm a bit surprised to see that you've stuck with Object as the common base of the hierarchy. What is the reason behind that, given that the impression from the recent discussions has been, IME, that most wanted a change?

Technically Object will always be the root as long as 'throw' can take
Object. I should have put at the top of the post that I assume the language
stays the same - if Walter changes what gets thrown then the root will
change. I have no idea what Walter thinks of changing the root.
So I proceeded given Object is the root, what should the next few branches
be? I argue the depth of the tree should be kept as small as practical so
that we don't end up with the random hierarchy like the current phobos and
Java (ie - fewer decisions for class writers means fewer mistakes). The key
is that the tree we have still needs to be useful and flexible.
I see Object and Exception have enough exception-friendly features except
for stack traces and perhaps other unknown features. If stack traces ever
get introduced to D we could wedge in another branch of the tree but
personally I'd prefer to do it though an interface implemented by Exception
and (for argument's sake I'll assume my proposal) AssertionFailure
(OutOfMemory makes me nervous wrt stack traces for reasons I posted in
another thread: where does the memory for the stack trace come from?). That
would keep the tree depth down while adding flexibility. Other features
could be added to Exception and/or through interfaces.

-Ben

ps - what does IME mean?


April 14, 2005
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d3ksf2$1vm$1@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d3kos2$2vnh$1@digitaldaemon.com...
>>I don't much care about the leaf-side hierarchy, as I think the root is far more important. I'm a bit surprised to see that you've stuck with Object as the common base of the hierarchy. What is the reason behind that, given that the impression from the recent discussions has been, IME, that most wanted a change?
>
> Technically Object will always be the root as long as 'throw' can
> take Object. I should have put at the top of the post that I
> assume the language stays the same - if Walter changes what gets
> thrown then the root will change. I have no idea what Walter
> thinks of changing the root.
> So I proceeded given Object is the root, what should the next few
> branches be? I argue the depth of the tree should be kept as small
> as practical so that we don't end up with the random hierarchy
> like the current phobos and Java (ie - fewer decisions for class
> writers means fewer mistakes). The key is that the tree we have
> still needs to be useful and flexible.
> I see Object and Exception have enough exception-friendly features
> except for stack traces and perhaps other unknown features. If
> stack traces ever get introduced to D we could wedge in another
> branch of the tree but personally I'd prefer to do it though an
> interface implemented by Exception and (for argument's sake I'll
> assume my proposal) AssertionFailure (OutOfMemory makes me nervous
> wrt stack traces for reasons I posted in another thread: where
> does the memory for the stack trace come from?). That would keep
> the tree depth down while adding flexibility. Other features could
> be added to Exception and/or through interfaces.

Ok. Makes sense. (Man, I need to get my paranoia gland sorted!! <g>)


> ps - what does IME mean?

In my estimation.



April 14, 2005
On Wed, 13 Apr 2005 22:33:19 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote:

<snip>

Looks good.

My first thought is that "SystemError" is the only one with "Error" in it's name. I think it's the most accurate description of what it is but it seemed odd that it was the only one. Thoughts?

> Questions:
> 1. what should the top few lines of the hierarchy look like?

These ones?

> Object
>   OutOfMemory
>   AssertionFailure (was AssertError:Error)
>      NoSwitchDefault (was SwitchError:Error)

they look good to me.

> 2. should modules that currently reuse one exception create subclasses?

Example? I have some vague idea of what you mean but I'd prefer to comment on something concrete.

> 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
>      throw a raw Exception)

My first thought is no, I say that because "Exception" doesn't tell me what went wrong, it just says something went wrong. What is the reason gc throws it? Shouldn't that be the name of the exception it throws?

> 4. what is missing?

Nothing I can think of at this time.

Regan
April 14, 2005
>> 2. should modules that currently reuse one exception create subclasses?
>
> Example? I have some vague idea of what you mean but I'd prefer to comment on something concrete.

std.format is one I had in mind. It reuses FormatError (aka FormatException) for all error conditions and I wonder if user code will want to catch and handle particular failures (eg invalid specifier, int overflow, the infamous formatArg, etc). Currently if they want to react differently to those situations the code would have to inspect the message string which is fragile. There are probably other modules with similar generous exception reuse.

>> 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
>>      throw a raw Exception)
>
> My first thought is no, I say that because "Exception" doesn't tell me what went wrong, it just says something went wrong. What is the reason gc throws it? Shouldn't that be the name of the exception it throws?

internal/gc/gc.d currently throws Error("incompatible gc versions") in
setGCHandle which is used to sync up dynamically loaded libraries. I thought
of adding GCException:Exception and GCVersionException:GCException but then
that seemed like overkill. One would think the code loading and syncing up a
dynamically loaded lib wouldn't want to treat GC errors differently from
whatever else that action can throw. I'm still not sure.
Another example that I decided in the other direction was the array casting
errors in internal/arraycast. That module throws raw Errors and I figured a
subclass of a general CastException would be useful to throw in an opCast
for a struct or class. So that one I added to the hierarchy.


April 14, 2005
On Thu, 14 Apr 2005 07:59:07 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote:
>>> 2. should modules that currently reuse one exception create subclasses?
>>
>> Example? I have some vague idea of what you mean but I'd prefer to comment
>> on something concrete.
>
> std.format is one I had in mind. It reuses FormatError (aka FormatException)
> for all error conditions and I wonder if user code will want to catch and
> handle particular failures

That was my thought also. If you wanted to "catch and handle particular failures" you'd need some way to distinguish them.

> (eg invalid specifier, int overflow, the infamous
> formatArg, etc). Currently if they want to react differently to those
> situations the code would have to inspect the message string which is
> fragile.

So, the question is "Do we need to catch and handle particular failures in this case?"
My answer, no idea sorry.

> There are probably other modules with similar generous exception
> reuse.

Indeed. What do you think the pros/cons of subclassing vs throwing <exception_name> with a differing 'cause' are in these sorts of cases?

>>> 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
>>>      throw a raw Exception)
>>
>> My first thought is no, I say that because "Exception" doesn't tell me
>> what went wrong, it just says something went wrong. What is the reason gc
>> throws it? Shouldn't that be the name of the exception it throws?
>
> internal/gc/gc.d currently throws Error("incompatible gc versions") in
> setGCHandle which is used to sync up dynamically loaded libraries. I thought
> of adding GCException:Exception and GCVersionException:GCException but then
> that seemed like overkill. One would think the code loading and syncing up a
> dynamically loaded lib wouldn't want to treat GC errors differently from
> whatever else that action can throw. I'm still not sure.

What other errors can arise? FileNotFound, PermissionDenied, GCVersionException?
i.e. might you want to catch FileNotFound and give the user a chance to find the dll for you?

> Another example that I decided in the other direction was the array casting
> errors in internal/arraycast. That module throws raw Errors and I figured a
> subclass of a general CastException would be useful to throw in an opCast
> for a struct or class. So that one I added to the hierarchy.

Makes sense.

Regan
April 14, 2005
Comments:
1. Assertion Failure and sub-classes should have stack tracing. Should they
then have a common ancestor with Exceptions? (see my post in other thread).
It would be cleaner if all stack-traced object inherited through the same
base object, but the functionality can be imported by other means.
2. As others have said, I would definitely rename SystemError to
SystemException (deprecating the old name for a while perhaps). It is really
a sore thumb...
3. I would trim on the numbers of exceptions. Examples:
#1: ParamException is enough, I don't think ParamNullException and
ParamRangeException are needed. Less exceptions means more consistency
overall in D programs. ParamException means the client code screwed up.
Stack trace should tell you where.
#2: ArrayCopyException... same thing: parent class is enough.
#3: Difference between NotSupportedException and NotImplementedException?
Conceptually, I undersand there is a difference. In practice though, it
means you called code that does nothing. I wouldeliminate one of the two.
#4: Base64CharException: parent is enough
#5: Shouldn't DateParseException be a ParamException?
#6: ArrayCastException: parent is enough
#7: What do StringException, ThreadException, ZipException and ZlibException
mean in practice? It tells us *where* the exception occured, not *what*
occured. The exception name should refer to what occured. For instance, if
Zlib failed because a file was not found, a FileOpenException should be
sent.

Honestly, before we reinvent the wheel, I believe we should take a long hard look at own C# and Java define their exception hierarchy and mimic it as much as possible. These languages have been in the field for some time and some thought went into their exceptions hierarchy design. I would leverage this thought process as much as possible.

The reason I'm saying that is that somehow this hierarchy seems contrived... It seems to stem from a desire to map what is currently there to something a little better (which would in itself be a *very* good thing, don't get me wrong). However, I believe a more in-depth redesign would be more profitable.

***
Walter, Ben, and all,

Taking a step back, I see in this community people actively participating, obviously willing to improve the language and make things better. This is extremely valuable. Why not use these resources and this talent in a more... productive manner? Maybe I have been away from newgroup for too long, but all these posts back and forth hardly seem productive to me. What seems to be going on is endless debates about points of detail, while overall not much is achieved. Don't get me wrong, debating is good. As long as it leads somewhere... I have proposed to spend time investigating stack tracing. You Ben are intend on redesigning the exception hierarchy. I am sure other people would like to contribute in various other ways.

Why doesn't Walter "elect" some people to make high level design proposals
on chosen topics?  I'm sure that over the years he's come to recognize
individuals who have made a sizeable contribution to D (like you Ben).
The idea would be to channel all our ideas to one person responsible for
drafting a high level design about a specific topic (subject expert). Walter
would later appose his seal (or not) on that document and implementation
could begin, by Walter himself or by a designated individual(s). Walter
would have the last word: if he believes the document does not adequately
covers possible design alternatives and/or that the suggested amendment is
inappropriate, he could veto it (at a political price, of course... ;)

The workload would be shared between Walter and the community and I am sure we would all reap the benefits quite rapidly. That is how open source projects work anyway, no? Walter would be the big Kauna and he would have a few lieutenants working for him. I know I'm not proposing anything new. It just appears to me that even at this point, Walter probably can't cope with all the threads, all the suggestions, all the bugs, etc.

Anyway, the bottom line for me I guess is that I'm willing to make a contribution to D if I can because I believe it has a lot of potential. However, I have no time to spend in newsgroup debating endlessly. I suppose it is probably the same for the most interesting elements in this community. I'm available, use me or lose me!  ;)

No kidding, even writing this, I'm afraid I'm losing my time. What if Walter's idea is that the exception hierarchy is 100% fine as it is? What impact do we have? On the other hand, if Walter elected you Ben as subject expert on this matter, well, I'd spend 5 times as much time as I spent writing this, making research on my own and proposing amendments a lot more tangible than "super-class is enough". I'd give alternatives, examples, etc. to make my point and try to convince you because in the end you would be writing the official proposal. We all know that consensus is something unachievable, so there must be one person to receive all comments on a given subject and weighs alternatives. As it stands, who's responsible for making a decision? At this stage, the D community lives on hope...

So, Walter, what say you?

Max



"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d3kkph$2t76$1@digitaldaemon.com...
> Over the past few days/weeks I've been going over the phobos exception usage. Below is my proposal for modifying the phobos exception class inheritance hierarchy (indenting indicates subclassing). I have no idea if Walter would actually accept anything close to this proposal, but I figure what the heck. See notes and questions at the end, too.
>
> Object
>    OutOfMemory
>    AssertionFailure (was AssertError:Error)
>       NoSwitchDefault (was SwitchError:Error)
>    Exception
>       ParamException (new)
>          ParamNullException (new)
>          ParamRangeException (new)
>       IndexException (new)
>          ArrayBoundsException (was ArrayBoundsError:Error)
>       CollectionCopyException (new)
>          ArrayCopyException (was Error in internal/arraycat.d)
>       NotSupportedException (new)
>       NotImplementedException (new)
>       AddressException
>       Base64Exception
>          Base64CharException
>       CastException (new)
>          ArrayCastException (was Error in internal/arraycast.d)
>       ConvException (was ConvError:Error)
>          ConvOverflowException (was ConvOverflowError:ConvError)
>       DateParseException (was DateParseError:Error)
>       SystemError (see Regan's code posted on thread about std.syserror)
>          FileException (was FileException:Exception)
>          SocketException (was SocketException:Exception)
>             SocketAcceptException
>          HostException (was HostException:Exception)
>          RegistryException (was RegistryException:Win32Exception)
>          ExeModuleException (was ExeModuleException:Exception)
>       FormatException (was FormatError:Error)
>       ModuleCtorException (was ModuleCtorError:Exception)
>       OpenRJException
>          DatabaseException
>          InvalidKeyException
>          InvalidTypeException
>       RegExpException (was RegExpError:Error)
>       StreamException
>          ReadException
>          WriteException
>          SeekException
>          StreamFileException
>             OpenException
>       StringException
>       ThreadException (was ThreadError:Error)
>          OutOfThreadsException (new)
>       URIException (was URIError:Error)
>       UTFException (was UtfError:Error)
>       ZipException
>       ZlibException
>
> Notes:
> 1. removed std.windows.registry.Win32Exception since it overlaps with
>      SystemError for Windows
> 2. remove FooError aliases for std.stream exceptions
> 3. some exceptions might be thrown with SystemError causes
>      (eg StreamFileException, ThreadException)
> 4. RegistryException is thrown once without a system error code
> 5. NotSupportedException will be a cause in
>      - std.mmfile some thrown FileExceptions
>      - std.stream in a StreamException that replaces a raw Exception
>      - std.zip in several ZipExceptions
> 6. Backwards incompatibilities are limited (hopefully) to class names
> involving Error
>    and subclassing Error. The subclassing Error switches to Exception
except
>    for asserts and switch defaults don't subclass Exception in the new
> scheme.
> 7. The array errors now subclass general reusable errors.
>
> Exception is defined as
> class Exception {
>     char[] msg;
>     Object cause; // new
>
>     this(char[] msg, Object cause = null) { // new
>         this.msg = msg;
>         this.cause = cause; // new
>     }
>
>     void print() {
>         printf("%.*s\n", msg);
>         if (cause) cause.print(); // new
>     }
>
>     char[] toString() { return msg; }
> }
>
> For the definition of SystemError see Regan's post http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282
>
> Questions:
> 1. what should the top few lines of the hierarchy look like?
> 2. should modules that currently reuse one exception create subclasses?
> 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
>      throw a raw Exception)
> 4. what is missing?
>
>


April 14, 2005
If I may complement my ealier proposal, it should be obvious that subject experts should have some kind of real-life industry knowledge and experience in the field... The last thing we want is having new grads drafting proposals... (not that I have anything against new grads mind you).

The subjects experts could even be voted on by the community itself (with prehaps Walter having a veto).

Max


"Maxime Larose" <mlarose@broadsoft.com> wrote in message news:d3lpvn$te3$1@digitaldaemon.com...
> Comments:
> 1. Assertion Failure and sub-classes should have stack tracing. Should
they
> then have a common ancestor with Exceptions? (see my post in other
thread).
> It would be cleaner if all stack-traced object inherited through the same
> base object, but the functionality can be imported by other means.
> 2. As others have said, I would definitely rename SystemError to
> SystemException (deprecating the old name for a while perhaps). It is
really
> a sore thumb...
> 3. I would trim on the numbers of exceptions. Examples:
> #1: ParamException is enough, I don't think ParamNullException and
> ParamRangeException are needed. Less exceptions means more consistency
> overall in D programs. ParamException means the client code screwed up.
> Stack trace should tell you where.
> #2: ArrayCopyException... same thing: parent class is enough.
> #3: Difference between NotSupportedException and NotImplementedException?
> Conceptually, I undersand there is a difference. In practice though, it
> means you called code that does nothing. I wouldeliminate one of the two.
> #4: Base64CharException: parent is enough
> #5: Shouldn't DateParseException be a ParamException?
> #6: ArrayCastException: parent is enough
> #7: What do StringException, ThreadException, ZipException and
ZlibException
> mean in practice? It tells us *where* the exception occured, not *what* occured. The exception name should refer to what occured. For instance, if Zlib failed because a file was not found, a FileOpenException should be sent.
>
> Honestly, before we reinvent the wheel, I believe we should take a long
hard
> look at own C# and Java define their exception hierarchy and mimic it as much as possible. These languages have been in the field for some time and some thought went into their exceptions hierarchy design. I would leverage this thought process as much as possible.
>
> The reason I'm saying that is that somehow this hierarchy seems
contrived...
> It seems to stem from a desire to map what is currently there to something
a
> little better (which would in itself be a *very* good thing, don't get me wrong). However, I believe a more in-depth redesign would be more profitable.
>
> ***
> Walter, Ben, and all,
>
> Taking a step back, I see in this community people actively participating, obviously willing to improve the language and make things better. This is extremely valuable. Why not use these resources and this talent in a
more...
> productive manner? Maybe I have been away from newgroup for too long, but all these posts back and forth hardly seem productive to me. What seems to be going on is endless debates about points of detail, while overall not much is achieved. Don't get me wrong, debating is good. As long as it
leads
> somewhere... I have proposed to spend time investigating stack tracing.
You
> Ben are intend on redesigning the exception hierarchy. I am sure other people would like to contribute in various other ways.
>
> Why doesn't Walter "elect" some people to make high level design proposals on chosen topics?  I'm sure that over the years he's come to recognize individuals who have made a sizeable contribution to D (like you Ben). The idea would be to channel all our ideas to one person responsible for drafting a high level design about a specific topic (subject expert).
Walter
> would later appose his seal (or not) on that document and implementation could begin, by Walter himself or by a designated individual(s). Walter would have the last word: if he believes the document does not adequately covers possible design alternatives and/or that the suggested amendment is inappropriate, he could veto it (at a political price, of course... ;)
>
> The workload would be shared between Walter and the community and I am
sure
> we would all reap the benefits quite rapidly. That is how open source projects work anyway, no? Walter would be the big Kauna and he would have
a
> few lieutenants working for him. I know I'm not proposing anything new. It just appears to me that even at this point, Walter probably can't cope
with
> all the threads, all the suggestions, all the bugs, etc.
>
> Anyway, the bottom line for me I guess is that I'm willing to make a contribution to D if I can because I believe it has a lot of potential. However, I have no time to spend in newsgroup debating endlessly. I
suppose
> it is probably the same for the most interesting elements in this
community.
> I'm available, use me or lose me!  ;)
>
> No kidding, even writing this, I'm afraid I'm losing my time. What if Walter's idea is that the exception hierarchy is 100% fine as it is? What impact do we have? On the other hand, if Walter elected you Ben as subject expert on this matter, well, I'd spend 5 times as much time as I spent writing this, making research on my own and proposing amendments a lot
more
> tangible than "super-class is enough". I'd give alternatives, examples,
etc.
> to make my point and try to convince you because in the end you would be writing the official proposal. We all know that consensus is something unachievable, so there must be one person to receive all comments on a
given
> subject and weighs alternatives. As it stands, who's responsible for
making
> a decision? At this stage, the D community lives on hope...
>
> So, Walter, what say you?
>
> Max
>
>
>
> "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d3kkph$2t76$1@digitaldaemon.com...
> > Over the past few days/weeks I've been going over the phobos exception usage. Below is my proposal for modifying the phobos exception class inheritance hierarchy (indenting indicates subclassing). I have no idea
if
> > Walter would actually accept anything close to this proposal, but I
figure
> > what the heck. See notes and questions at the end, too.
> >
> > Object
> >    OutOfMemory
> >    AssertionFailure (was AssertError:Error)
> >       NoSwitchDefault (was SwitchError:Error)
> >    Exception
> >       ParamException (new)
> >          ParamNullException (new)
> >          ParamRangeException (new)
> >       IndexException (new)
> >          ArrayBoundsException (was ArrayBoundsError:Error)
> >       CollectionCopyException (new)
> >          ArrayCopyException (was Error in internal/arraycat.d)
> >       NotSupportedException (new)
> >       NotImplementedException (new)
> >       AddressException
> >       Base64Exception
> >          Base64CharException
> >       CastException (new)
> >          ArrayCastException (was Error in internal/arraycast.d)
> >       ConvException (was ConvError:Error)
> >          ConvOverflowException (was ConvOverflowError:ConvError)
> >       DateParseException (was DateParseError:Error)
> >       SystemError (see Regan's code posted on thread about std.syserror)
> >          FileException (was FileException:Exception)
> >          SocketException (was SocketException:Exception)
> >             SocketAcceptException
> >          HostException (was HostException:Exception)
> >          RegistryException (was RegistryException:Win32Exception)
> >          ExeModuleException (was ExeModuleException:Exception)
> >       FormatException (was FormatError:Error)
> >       ModuleCtorException (was ModuleCtorError:Exception)
> >       OpenRJException
> >          DatabaseException
> >          InvalidKeyException
> >          InvalidTypeException
> >       RegExpException (was RegExpError:Error)
> >       StreamException
> >          ReadException
> >          WriteException
> >          SeekException
> >          StreamFileException
> >             OpenException
> >       StringException
> >       ThreadException (was ThreadError:Error)
> >          OutOfThreadsException (new)
> >       URIException (was URIError:Error)
> >       UTFException (was UtfError:Error)
> >       ZipException
> >       ZlibException
> >
> > Notes:
> > 1. removed std.windows.registry.Win32Exception since it overlaps with
> >      SystemError for Windows
> > 2. remove FooError aliases for std.stream exceptions
> > 3. some exceptions might be thrown with SystemError causes
> >      (eg StreamFileException, ThreadException)
> > 4. RegistryException is thrown once without a system error code
> > 5. NotSupportedException will be a cause in
> >      - std.mmfile some thrown FileExceptions
> >      - std.stream in a StreamException that replaces a raw Exception
> >      - std.zip in several ZipExceptions
> > 6. Backwards incompatibilities are limited (hopefully) to class names
> > involving Error
> >    and subclassing Error. The subclassing Error switches to Exception
> except
> >    for asserts and switch defaults don't subclass Exception in the new
> > scheme.
> > 7. The array errors now subclass general reusable errors.
> >
> > Exception is defined as
> > class Exception {
> >     char[] msg;
> >     Object cause; // new
> >
> >     this(char[] msg, Object cause = null) { // new
> >         this.msg = msg;
> >         this.cause = cause; // new
> >     }
> >
> >     void print() {
> >         printf("%.*s\n", msg);
> >         if (cause) cause.print(); // new
> >     }
> >
> >     char[] toString() { return msg; }
> > }
> >
> > For the definition of SystemError see Regan's post http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282
> >
> > Questions:
> > 1. what should the top few lines of the hierarchy look like?
> > 2. should modules that currently reuse one exception create subclasses?
> > 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
> >      throw a raw Exception)
> > 4. what is missing?
> >
> >
>
>


April 14, 2005
"Maxime Larose" <mlarose@broadsoft.com> wrote in message news:d3lpvn$te3$1@digitaldaemon.com...
> Comments:
> 1. Assertion Failure and sub-classes should have stack tracing. Should
> they
> then have a common ancestor with Exceptions? (see my post in other
> thread).
> It would be cleaner if all stack-traced object inherited through the same
> base object, but the functionality can be imported by other means.

Adding a common base class between Object and Exception would be easily added with 100% backwards compatibility once stack traces became possible. Why cross that bridge before we need to? In other words, with the hierarchy I've proposed we leave open the option of how to implement stack tracing. Given that it doesn't exist yet it would be premature to impose any API for it. If I'm mistaken about my assertion that adding a base class later is 100% backwards compatible then I totally agree we need to figure this out now.

> 2. As others have said, I would definitely rename SystemError to
> SystemException (deprecating the old name for a while perhaps). It is
> really
> a sore thumb...

ok - I'm very open to hearing from people. I have no strong opinion either way. So please people speak up.

> 3. I would trim on the numbers of exceptions. Examples:
> #1: ParamException is enough, I don't think ParamNullException and
> ParamRangeException are needed. Less exceptions means more consistency
> overall in D programs. ParamException means the client code screwed up.
> Stack trace should tell you where.

As I explained in another thread ParamNull is useful for two reasons:
1) shortens the throw code and makes it more consistent. All I have to type
is
  throw new ParamNullException("var name")
instead of
  throw new ParamException("Parameter can't be null","var name")
Since null parameter checks are very common it makes sense to make it easy.
2) allows different exceptions for something being null and something being
null but out of the desired range or for some other reason.
I could see removing ParamRangeException, though, and having user code just
throw a ParamException for those.

> #2: ArrayCopyException... same thing: parent class is enough.

sounds reasonable.

> #3: Difference between NotSupportedException and NotImplementedException? Conceptually, I undersand there is a difference. In practice though, it means you called code that does nothing. I wouldeliminate one of the two.

It's a useful distinction I picked up from Java. You throw NotImpl in stuff you haven't gotten to yet but plan to and NotSupported in stuff that the OS or whatever won't ever support.

> #4: Base64CharException: parent is enough

could be. I just kept what was there before and didn't look into that very closely.

> #5: Shouldn't DateParseException be a ParamException?

good idea

> #6: ArrayCastException: parent is enough

opCast overloads should be able to throw a similar exception as casting an array IMO. Currently casting an array throws a bare Error so we could just go back to that.

> #7: What do StringException, ThreadException, ZipException and
> ZlibException
> mean in practice? It tells us *where* the exception occured, not *what*
> occured. The exception name should refer to what occured. For instance, if
> Zlib failed because a file was not found, a FileOpenException should be
> sent.

That's what the 'cause' is for. It can be used to both chain exceptions as they get caught and thrown up the stack or it can be used to indicate what happened that caused the first exception to be thrown. In my original post I indicated where I think 'cause' should be used but that was a first pass and people who know more about the particular modules should do whatever they think makes sense. To address your particular example of Zlib and file-not-found I can't see any file management in std.zlib so I'm not sure what you are referring to.

> Honestly, before we reinvent the wheel, I believe we should take a long
> hard
> look at own C# and Java define their exception hierarchy and mimic it as
> much as possible. These languages have been in the field for some time and
> some thought went into their exceptions hierarchy design. I would leverage
> this thought process as much as possible.

agreed.

> The reason I'm saying that is that somehow this hierarchy seems
> contrived...
> It seems to stem from a desire to map what is currently there to something
> a
> little better (which would in itself be a *very* good thing, don't get me
> wrong). However, I believe a more in-depth redesign would be more
> profitable.

please keep the suggestions coming. My proposal was trying to rearrange and unify the existing exceptions so I could very well believe it didn't go far enough in changing things around. Keep in mind the details of the hierarchy will change as phobos modules move around and change.

[snip]

> ***
> Walter, Ben, and all,
>
> Taking a step back, I see in this community people actively participating,
> obviously willing to improve the language and make things better. This is
> extremely valuable. Why not use these resources and this talent in a
> more...
> productive manner? Maybe I have been away from newgroup for too long, but
> all these posts back and forth hardly seem productive to me. What seems to
> be going on is endless debates about points of detail, while overall not
> much is achieved. Don't get me wrong, debating is good. As long as it
> leads
> somewhere... I have proposed to spend time investigating stack tracing.
> You
> Ben are intend on redesigning the exception hierarchy. I am sure other
> people would like to contribute in various other ways.

I'm confident *something* will happen - the question is exactly what Walter (and the community) is willing to accept. Walter goes with the community on many things (though not all obviously) so as long as we have an open and representative debate I see it as all good stuff.

[snip good stuff]



« First   ‹ Prev
1 2