On Tue, Apr 02, 2013 at 01:29:00PM -0400, Jonathan M Davis wrote: > On Tuesday, April 02, 2013 17:56:07 Lars T. Kyllingstad wrote: > > On Monday, 1 April 2013 at 22:26:39 UTC, Jonathan M Davis wrote: > > > In general, I'd strongly suggest having subclasses for the various > > > "Kind"s in addition to the kind field. That way, you have the > > > specific exception types if you want to have separate catch blocks > > > for different error types, and you have the kind field if you just > > > want to catch the base exception. > > > > Then you'd have two points of maintenance when you wish to add or > > remove an error category. > > True, but it's also trivial to do. But if we had to decide between > basically putting error codes on exceptions and using sub-classes, I'd > vote for subclasses in most cases - though errno would need to go the > error code in the exception route, since it has different meanings in > different contexts and would risk an absolute explosion of exception > types anyway; though it should probably be translated to a more > meaningful exception based on context with the errno exception being > chained to it - which is what you suggest in the DIP IIRC. In general > though, I'd favor subclasses, and I don't think that it's all that big > a deal to give them each specific error codes when you want the base > class to have an error code like you're suggesting. [...]
IMO, errno should be stored as-is in a dedicated ErrnoException. Any interpretation of errno thereof should wrap this ErrnoException inside another hierarchy-appropriate exception. For example: void lowLevelIORoutine(...) { if (osRead(...) < 0) { throw ErrnoException(errno); } ... } void libraryRoutine(...) { try { lowLevelIORoutine(...); } catch(ErrnoException e) { if (e.errno == ENOENT) { // Chain ErrnoException to FileNotFoundException throw new FileNotFoundException(e.msg, e); } else if (e.errno == ENOSPC) { // Chain ErrnoException to DiskFullException throw new DiskFullException(e.msg, e); } else { // etc. ... } } } This way, user code can catch IOException rather than ErrnoException, but errno is still accessible via .next should the user code want to deal directly with errno: void userCode() { try { auto f = File("/some/path/to/file"); } catch(IOException e) { if ((auto f = cast(ErrnoException) e.next) !is null) { handleErrno(f.errno); } ... } I think this would be a good use of the current .next field in Exception. T -- A mathematician is a device for turning coffee into theorems. -- P. Erdos