Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 11, 2005 recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
I'm looking into the Error/Exception situation in phobos and previous posts by Walter and others generally argued that Exceptions are recoverable and Errors are not. I believe there isn't an application-independent definition of what recoverable means and I would like to pursue an exception class hierarchy that doesn't distinguish the two (ie like C#). The distinction in Java is poorly designed and can be covered in D by subclassing Object directly. The existing class heirarchy in phobos and user code also seemingly randomly subclasses Error or Exception. For example the class hierachy I have in mind looks like Object OutOfMemory AssertionFailure Exception FileException StreamException ... etc, all the other exceptions and subclasses ... where Exception is 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 } For reference see http://www.digitalmars.com/d/archives/digitalmars/D/6049.html http://www.digitalmars.com/d/archives/digitalmars/D/9556.html http://www.digitalmars.com/d/archives/digitalmars/D/10415.html comments? |
April 11, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | On Mon, 11 Apr 2005 19:37:21 -0400, Ben Hinkle <bhinkle@mathworks.com> wrote: > I'm looking into the Error/Exception situation in phobos and previous posts > by Walter and others generally argued that Exceptions are recoverable and > Errors are not. That seemed to me to be the general consesus. > I believe there isn't an application-independent definition > of what recoverable means and I would like to pursue an exception class > hierarchy that doesn't distinguish the two (ie like C#). I agree. > The distinction in Java is poorly designed and can be covered in D by subclassing Object > directly. So if you want an un-recoverable error you subclass object and never catch Object directly? > The existing class heirarchy in phobos and user code also > seemingly randomly subclasses Error or Exception. That's the way it seems to me also. That and the docs should note the exceptions/errors thrown by each method/function, but that's a task for after this one. > For example the class hierachy I have in mind looks like > Object > OutOfMemory > AssertionFailure > Exception > FileException > StreamException > ... etc, all the other exceptions and subclasses ... Where does "missing/incorrect parameter" fit in? My feeling is that it's a subclass of Object and not Exception? or in fact should it be handled with an assert statement and thus be an AssertionFailure? But you probably didn't want specifics at this point, so I'll be quiet now. ;) > where Exception is > 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 > } > > For reference see > http://www.digitalmars.com/d/archives/digitalmars/D/6049.html > http://www.digitalmars.com/d/archives/digitalmars/D/9556.html > http://www.digitalmars.com/d/archives/digitalmars/D/10415.html > > comments? I think it's a great idea, I believe it needs to be done before D 1.0 and I'd like to help in any way I can. Regan |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | >> The distinction in Java is poorly designed and can be covered in D by >> subclassing Object >> directly. > > So if you want an un-recoverable error you subclass object and never catch Object directly? What do you have in mind as a user-defined unrecoverable error? I was expecting users to subclass Exception (or some subclass of Exception) by convention. The only case that comes to mind where I could see subclassing something else would be to mimic the built-in AssertionFailure by subclassing it and adding some custom behavior. From a technical point of view anyone can throw or catch any Object. >> For example the class hierachy I have in mind looks like >> Object >> OutOfMemory >> AssertionFailure >> Exception >> FileException >> StreamException >> ... etc, all the other exceptions and subclasses ... > > Where does "missing/incorrect parameter" fit in? My feeling is that it's a subclass of Object and not Exception? or in fact should it be handled with an assert statement and thus be an AssertionFailure? I see assertion failures as different than a incorrect parameters. An assertion is a statement that must *always* be true no matter how the user has called your function or used your object. If an assertion fails the internal state of your part of the system is in doubt. By contrast an incorrect parameter is to be expected. It can get confusing when one starts to consider the user code as part of the same system as the function being called, but then the user code can have asserts to make sure its own interal state is consistent. To be concrete I was thinking that ArgumentException would subclass Exception and have the .Net hierarchy Exception ArgumentException ArgumentNullException ArgumentOutOfRangeException > But you probably didn't want specifics at this point, so I'll be quiet now. ;) please ask any/all questions. The more the better. |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | On Mon, 11 Apr 2005 21:01:40 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote: >>> The distinction in Java is poorly designed and can be covered in D by >>> subclassing Object >>> directly. >> >> So if you want an un-recoverable error you subclass object and never catch >> Object directly? > > What do you have in mind as a user-defined unrecoverable error? Nothing new, I was looking at: OutOfMemory AssertionFailure and thought, for most applications these are treated as unrecoverable errors. > I was > expecting users to subclass Exception (or some subclass of Exception) by > convention. Agreed, 99% (maybe 100%) of the time. I wondered however whether it was possible for a user to want to create an unrecoverable error, i.e. for their application "Foo" is unrecoverable, if so they can do so, by subclassing Object, and ensuring they never catch(Object), or catch it in main and exit. Thus their application will always fail hard on "Foo". > The only case that comes to mind where I could see subclassing > something else would be to mimic the built-in AssertionFailure by > subclassing it and adding some custom behavior. Yeah, to add their own custom unrecoverable error of some sort. > From a technical point of view anyone can throw or catch any Object. Yep. I was thinking in terms of a style/convention which would be used to add custom unrecoverable errors. >>> For example the class hierachy I have in mind looks like >>> Object >>> OutOfMemory >>> AssertionFailure >>> Exception >>> FileException >>> StreamException >>> ... etc, all the other exceptions and subclasses ... >> >> Where does "missing/incorrect parameter" fit in? My feeling is that it's a >> subclass of Object and not Exception? or in fact should it be handled with >> an assert statement and thus be an AssertionFailure? > > I see assertion failures as different than a incorrect parameters. An > assertion is a statement that must *always* be true no matter how the user > has called your function or used your object. If an assertion fails the > internal state of your part of the system is in doubt. By contrast an > incorrect parameter is to be expected. It can get confusing when one starts > to consider the user code as part of the same system as the function being > called, but then the user code can have asserts to make sure its own interal > state is consistent. What you say makes sense to me. I've never really used assertions. Where I was getting confused was that I was looking at it backwards, eg. foo(5) if '5' is an invalid parameter, this will *always* fail. foo(<convert input from user to int>); this will fail sometimes. is there any difference in how the calls above should be handled? or should both simply be "ArgumentOutOfRangeException" > To be concrete I was thinking that ArgumentException > would subclass Exception and have the .Net hierarchy > Exception > ArgumentException > ArgumentNullException > ArgumentOutOfRangeException Call me lazy but "ArgumentOutOfRangeException" seems like a really long name to use. Apart from that, sounds good. Regan |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | >> I was >> expecting users to subclass Exception (or some subclass of Exception) by >> convention. > > Agreed, 99% (maybe 100%) of the time. I wondered however whether it was possible for a user to want to create an unrecoverable error, i.e. for their application "Foo" is unrecoverable, if so they can do so, by subclassing Object, and ensuring they never catch(Object), or catch it in main and exit. Thus their application will always fail hard on "Foo". ok. Seems fine to me. >> The only case that comes to mind where I could see subclassing something else would be to mimic the built-in AssertionFailure by subclassing it and adding some custom behavior. > > Yeah, to add their own custom unrecoverable error of some sort. > >> From a technical point of view anyone can throw or catch any Object. > > Yep. I was thinking in terms of a style/convention which would be used to add custom unrecoverable errors. I think if we have a convention something is wrong :-P. Why have a convention for something that is discouraged? > foo(5) > if '5' is an invalid parameter, this will *always* fail. > > foo(<convert input from user to int>); > this will fail sometimes. > > is there any difference in how the calls above should be handled? or should both simply be "ArgumentOutOfRangeException" Personally I would prefer that ArgumentOutOfRangeException be used for arguments to functions that get checked at the start of the function. User input should get treated more gracefully than throwing an exception IMO: class InputOutOfRangeException {...} bar() { barstart: int x = ... prompt the user ... if (x == 5) {printf("try again doofus"); goto barstart;} foo(x); } void foo(int x) { if (x == 5) throw new ArgumentOutOfRangeException("Caller is a doofus"); } >> To be concrete I was thinking that ArgumentException >> would subclass Exception and have the .Net hierarchy >> Exception >> ArgumentException >> ArgumentNullException >> ArgumentOutOfRangeException > > Call me lazy but "ArgumentOutOfRangeException" seems like a really long name to use. Yeah. I agree. I'm tempted to suggest using Error instead of Exception because it is easier to read and type but I have a feeling that would send confusing signals to people used to "exceptions" and Exception. There was an earlier thread about names but I only vaguely remember Exception "won". Maybe we could shorten these ArgumentExceptions to ArgExceptions or ParamException since it's obvious what Arg and Param mean. So how about ParamException ParamNullException ParamRangeException > Apart from that, sounds good. ok |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | On Mon, 11 Apr 2005 22:52:46 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote: >>> The only case that comes to mind where I could see subclassing >>> something else would be to mimic the built-in AssertionFailure by >>> subclassing it and adding some custom behavior. >> >> Yeah, to add their own custom unrecoverable error of some sort. >> >>> From a technical point of view anyone can throw or catch any Object. >> >> Yep. I was thinking in terms of a style/convention which would be used to >> add custom unrecoverable errors. > > I think if we have a convention something is wrong :-P. Why have a > convention for something that is discouraged? Because unless we address the issue (of defining a custom unrecoverable error) people will do it anyway and might do it in some other weird way. At least this way we can explain why it's discouraged, when it might be okay to use it and how to use it. I'm not suggesting we encourage it, just that we acknowledge it's existance and give a suggestion. >> foo(5) >> if '5' is an invalid parameter, this will *always* fail. >> >> foo(<convert input from user to int>); >> this will fail sometimes. >> >> is there any difference in how the calls above should be handled? or >> should both simply be "ArgumentOutOfRangeException" > > Personally I would prefer that ArgumentOutOfRangeException be used for > arguments to functions that get checked at the start of the function. User > input should get treated more gracefully than throwing an exception IMO: > class InputOutOfRangeException {...} > bar() { > barstart: > int x = ... prompt the user ... > if (x == 5) {printf("try again doofus"); goto barstart;} > foo(x); > } > void foo(int x) { > if (x == 5) throw new ArgumentOutOfRangeException("Caller is a doofus"); > } Thanks, that makes sense. >>> To be concrete I was thinking that ArgumentException >>> would subclass Exception and have the .Net hierarchy >>> Exception >>> ArgumentException >>> ArgumentNullException >>> ArgumentOutOfRangeException >> >> Call me lazy but "ArgumentOutOfRangeException" seems like a really long >> name to use. > > Yeah. I agree. I'm tempted to suggest using Error instead of Exception > because it is easier to read and type but I have a feeling that would send > confusing signals to people used to "exceptions" and Exception. There was an > earlier thread about names but I only vaguely remember Exception "won". I think you're right (on both points). > Maybe we could shorten these ArgumentExceptions to ArgExceptions or > ParamException since it's obvious what Arg and Param mean. So how about > ParamException > ParamNullException > ParamRangeException > Just thinking about this, null and out of range are effectively the same thing, as null is "out of range" for a parameter that "cannot be null'. So we *could* just combine them. But then, of course, the reason for not combining them is so we can catch them seperately: void foo(int a){} try { foo(5); } catch(ParamNullException e) { } catch(ParamRangeException e) { } Otherwise we could just say: class ParamException { this(char[] param, char[] problem) { } } And have it print "ParamException: (%s) is %s", eg: "ParamException: (a) is out of range" "ParamException: (a) is null" "ParamException: (a) is not my favourite number" "ParamException: (a) is unlucky for some" <Warning: wacky idea> It's a pity the class tree isn't more 'obvious' then we could simply drop the redundant 'Exception' alltogether. eg. Exception Parameter Null OutOfRange Is this: try { } catch(OutOfRange e) { } really that opaque that it requires this: try { } catch(ParamRangeException e) { } ? Of course, it then becomes possible to have collisions within the tree. Exception Aaaaa Here Bbbbb Here Exception.Aaaaa.Here Exception.Bbbbb.Here are both called "Here". </wacky idea> Regan |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | "Regan Heath" <regan@netwin.co.nz> wrote in message news:opso3kiga523k2f5@nrage.netwin.co.nz... > On Mon, 11 Apr 2005 21:01:40 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote: >>>> The distinction in Java is poorly designed and can be covered >>>> in D by >>>> subclassing Object >>>> directly. >>> >>> So if you want an un-recoverable error you subclass object and >>> never catch >>> Object directly? >> >> What do you have in mind as a user-defined unrecoverable error? > > Nothing new, I was looking at: > OutOfMemory > AssertionFailure > > and thought, for most applications these are treated as unrecoverable errors. They may be, but that's quite wrong. OutOfMemory is practically unrecoverable, but should not be classed as an unrecoverable exception. Conversely, AssertionFailure is practically recoverable, but most certainly should be classed as unrecoverable. (And the language should mandate and enforce the irrecoverability.) |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:d3f1nh$rj4$1@digitaldaemon.com... > I'm looking into the Error/Exception situation in phobos and > previous posts > by Walter and others generally argued that Exceptions are > recoverable and > Errors are not. I believe there isn't an application-independent > definition > of what recoverable means An exception that may not be quenched, or in whose quenching the runtime takes over to terminate the process. Naturally, the system should provide an opportunity for cleanup of arbitrary sophistication, but the infrastructure should not support resuming normal processing. However meandering the path - as a consequence of the requirements of the application (e.g. dumping unsaved data in as fine a form as possible) - it must lead to process termination. Off the top of my head, only CP violations are unrecoverable, so it's not exactly >and I would like to pursue an exception class > hierarchy that doesn't distinguish the two (ie like C#). The > distinction in > Java is poorly designed and can be covered in D by subclassing > Object > directly. The existing class heirarchy in phobos and user code > also > seemingly randomly subclasses Error or Exception. All of the that speaks to the likelihood that those hierarchies were ill-considered, rather than that there's an intrinsic problem in segregating the exceptions/errors. In my C++ work, I use exception classes (always derived directly/indirectly from std::exception) for exceptions, and types derived from ::stlsoft::unrecoverable for, er, unrecoverable errors. Works a treat, and never caused any probs. (I've had this stuff, coupled with a release-mode contract enforcement, and verbose, but immediate, application termination in a real-time multi-protocol financial system running the last 4-5 months. It caught two fundamental design oversights in the first week, and hasn't uttered a peep since. All is working tickety-boo.) > For example the class hierachy I have in mind looks like > Object > OutOfMemory > AssertionFailure > Exception > FileException > StreamException > ... etc, all the other exceptions and subclasses ... > > where Exception is > 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 > } > > For reference see http://www.digitalmars.com/d/archives/digitalmars/D/6049.html http://www.digitalmars.com/d/archives/digitalmars/D/9556.html http://www.digitalmars.com/d/archives/digitalmars/D/10415.html > > comments? Problems with the above: 1. I want to see the ability to throw/catch an Object removed. (Or, if someone can possibly proffer a justification for wanting to do that - what has it ever benefited anyone in C++ to be able to throw a double? - incur a warning.) What's wrong with something Throwable? It's not like anyone will (or at least should!) be mixing an exception's duties with some other functionality, so there's no need to fear the constraints of a strict single-inheritance hierarchy. 2. I grok that you've identified the strange nature of OutOfMemory, in so far as it's theoretically recoverable but practically irrecoverable (except when one is supplying custom allocation). I agree that it's not a simple straightforward issue. I'd suggest that this is the one area that needs more thinking (including how other resource exhaustion might relate). 3. AssertionFailure - which I presume is the parent to a more detailed CP hierarchy - should be an Error, and irrecoverable (as per discussion above). I'd started work some months ago on suggestions for how Errors should be intrinsically handled within the language. I'll try and dig it out and post it. But, AFAICR, I posit that they should be analogous to function-try blocks in C++: it's fine (in fact professionally questionable not!) to catch them and exercise the application-specific level of informing of the user / dumping data / logging to SysLog/event-log/file/whatever, but the runtime, *in all threads*, will always rethrow any caught error, and will also provide intrinsic "catch(Error) { exit(EXIT_FAILURE); }" at the topmost level. The way I achieve this in the ::stlsoft::unrecoverable type is by ref-counting (similar to the shared_ptr mechanism) and the last one (copy, that is) out turns the lights off; it works a treat, as I mentioned above, and is not the least constricting, since it kindly waits until you've finished all your cleanup, even if you do several levels of cleanup by rethrowing the error. But since D holds exception objects by reference, all that jazz is unnecessary. In any case, such things are far better encapsulated in the language given that we (as I assert we do) want to avoid throwing of arbitrary types. I know this is going to stir the same hornet's nest of people who feel like it's big-brother-ism, or who don't understand that a program that has violated its design is, from then on, invalid and open to *any* behaviour (obviously the more exotic things, like bringing down the internet or signalling to aliens that we want to be liberated by a benevolent megamilitarist, are somewhat less likely than the more prosaic). Killing it is the only right thing to do. And it's also the effective and convenient thing to do. As I've said, I've been running this stuff in the real world for some time, and clients always shit themselves at the prospect, but then completely come around when they see the speed at which the code reaches a point where it's no longer violating its design. In the words of the Pragmatic Programmers (section "DBC and Crashing Early", pp115, of TPP): "It's much easier to find and diagnose the problem by crashing early, at the site of the problem." There is one valid scenario where errors should be quenchable: debuggers. For that, I have no immediate prescription, but I'm sure we can find a way to facilitate that without breaking the clean (and easily understand) delineation between exceptions and errors. (One idea might be that a base library function to turn on error quenching could be tied to the security infrastructure used by debuggers. Those with more experience than me in writing debuggers can no doubt some sense of this.) Charon |
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | > Off the top of my head, only CP violations are unrecoverable, so it's not exactly
onerous or limiting
|
April 12, 2005 Re: recoverable and unrecoverable errors or exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | On Tue, 12 Apr 2005 15:16:55 +1000, Matthew <admin@stlsoft.dot.dot.dot.dot.org> wrote: > "Regan Heath" <regan@netwin.co.nz> wrote in message > news:opso3kiga523k2f5@nrage.netwin.co.nz... >> On Mon, 11 Apr 2005 21:01:40 -0400, Ben Hinkle >> <ben.hinkle@gmail.com> wrote: >>>>> The distinction in Java is poorly designed and can be covered >>>>> in D by >>>>> subclassing Object >>>>> directly. >>>> >>>> So if you want an un-recoverable error you subclass object and >>>> never catch >>>> Object directly? >>> >>> What do you have in mind as a user-defined unrecoverable error? >> >> Nothing new, I was looking at: >> OutOfMemory >> AssertionFailure >> >> and thought, for most applications these are treated as >> unrecoverable errors. > > They may be, but that's quite wrong. > > OutOfMemory is practically unrecoverable, but should not be classed > as an unrecoverable exception. Agreed, in part, why "class" it as anything but what it is? > Conversely, AssertionFailure is practically recoverable, but most > certainly should be classed as unrecoverable. As above, why "class" it as anything but what it is? > (And the language > should mandate and enforce the irrecoverability.) Disagree. Regan |
Copyright © 1999-2021 by the D Language Foundation