The Right Approach to Exceptions

Jacob Carlborg doob at
Sun Feb 19 03:43:12 PST 2012

On 2012-02-18 23:26, Jonathan M Davis wrote:
> On Saturday, February 18, 2012 20:20:23 deadalnix wrote:
>> I think your oppinion here is shaped by C++. For what I experienced, in
>> C++, exception are only usefull for very important problem you cannot
>> possibly solve, and at the best log the error and exit.
>> An exemple is std::bad_alloc .
>> However, in D, I think this is more the role of an Errors. Exception are
>> something « softer ». It will alert you on problems your program
>> encounter, but that are recoverable.
>> You cannot recover from any exception at any place (sometime, you just
>> cannot at all).
>> Let's get an exemple : your program ask a file to the user and do some
>> operations with this file. If the file doesn't exists, you can prompt
>> for another file to the user with a meaningful message and start again.
>> However, the first version of your program can just ignore that case and
>> fail with a less specific handler in firsts versions.
>> You cannot achieve something like that if you don't have a useful type
>> to rely on. Here something like FileNotFoundException is what you want.
>> The type of the exception must depend on the problem you are facing, not
>> on the module that trhow it. I see a lot of people doing the «
>> MyProgramException » or « MyLibException » but that doesn't make sense.
>> In this case, you are just making things harder.
>> Back on the original subject, GetOptException is not what you want. As
>> getopt is supposed to handle command line parameters, you'll use
>> exception like : MissingParameterException, WrongFormatException,
>> UnknowParameterException or anything that is meaningful.
>> Those Exceptions would inherit from something like CommandLineException.
>> This is useful because it describe what you are facing. Because you cant
>> to know what is the problem, not which piece of code face the problem.
>> If this politic is choosen, then It would make sense to have several
>> modules of phobos throwing exceptions of the same type, or inheriting
>> from the same base class.
>> Exception type is a convenient way to filter what you catch and what you
>> don't know how to handle at this point.
> In general, I agree with all of this. I very much think that having typed
> exceptions makes a lot of sense. In general, I think that Java got exceptions
> right (ignoring the issue with checked exceptions). Having typed exceptions
> works really well.
> In the case of getopt, what we want is a GetOptException which is for anything
> which goes wrong with getopt so that someone can catch that exception type if
> they want to just handle the case wheree getopt throws but don't want to
> swallow other exception types by calling exception and pretty much just want
> to print an error and exit the program or continue without any comand-line
> arguments if that's what they prefer to do.

Isn't that what CommandLineException would be? Or would "getopt" throw 
other exceptions that would not derive from CommandLineException? So we 
end up with this:

                /      \
               /        \
              /          \
CommandLineException  SomeKindOfOtherException


> Then you have other exception types derived from GetOptException which deal
> with specific types of issues - such as FlagArgumentMissingException,
> InvalidFlagArgumentException, UnknownFlagException. Each of those exception
> types could then give information which specifically pertains to those errors -
> such as the flag that had a problem, the type that the flag is supposed to
> receive, the type that the flag actually received, the invalid value that the
> flag was given, etc. Such exceptions can then allow you to properly handle and
> report problems with command-line arguments. Right now, all you know is that
> something went wrong, and pretty much the best that you can do is print out
> that something went wrong. You can do any decent error handling at all. You
> need specific exception types which give you the appropriate information in
> order to do that.
> Another example is FileException. It would be benificial to have exceptions
> like FileNotFoundException, NotFileException, NotDirException,
> AccessDeniedException, etc which are derived from FileException. Then programs
> could handle the specific instance of what went wrong nice and cleanly rather
> than having to look at error codes. At least FileException provides an error
> code, but that makes for much uglier handling code assuming that you even have
> any clue what the error codes mean. And since the error codes can vary from OS
> to OS, you end up with system-specific error handling code if you try and use
> errno. Whereas if std.file just translated the error code to the correct
> exception type, you're then very cleanly informed as to what the problem was
> and can catch the exception based on which situtations you can recover from
> and which you can't as well as having different catch blocks to handle different
> problems differently.
> Simply having an exception type per module is somewhat better than just having
> Exception, because it gives you a better idea of what went wrong (e.g. you got
> a UTFException rather than a FileException), but it's still way too general in
> a lot of cases, and I can see why some would think that it creates needless
> boilerplate code. Also, in some cases, having exception types derive from more
> general exceptions than what the module focuses on can be useful. For
> instance, Java has IOException as the base for all IOExceptions. FileException
> could be derived from that, and then and std.stdio could could have
> their exception types derive from that as well. Then you could specifically
> handle all exceptions related to I/O together.
> I'm completely sold on typed exceptions, but I think that we could do better
> with them than we're currently doing.
> - Jonathan M Davis

Otherwise I completely agree.

/Jacob Carlborg

More information about the Digitalmars-d mailing list