In Python I can create my own thin exceptions (i.e. just different type for convenience of identification in a catch block, no added functionality) by:
class MyError(ExceptionBaseClass): pass Even in C++ I can do just: struct MyException: public std::exception {}; But in D: $ cat except.d class MyException: Exception {} $ dmd -c except.d except.d(1): Error: class foo.MyException cannot implicitly generate a default ctor when base class object.Exception is missing a default ctor OK so I dig up /usr/include/dmd/druntime/import/object.d: which doesn't have a default ctor but does have a user-defined one, which then disables the default: class Exception : Throwable { @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) } OK fine but then I didn't get why I had to write that long constructor with msg, file, __FILE__ etc every time I subclassed exception, so I did: $ cat except.d class MyException: Exception { this() { super(""); } } void main() { throw new MyException; } But it didn't give the expected results: $ dmd except.d $ ./except except.MyException@except.d(1) ... ... since the line number is wrong. OK so the reason is that the constructor which has the default arguments of __FILE__ and __LINE__ is called not at line 2 but at line 1 i.e. in the declaration of the subclass. So I am forced to write out all that stuff with __FILE__ etc yet again: $ cat except.d class MyException: Exception { this(string msg = "", string file = __FILE__, size_t line = __LINE__) { super("", file, line); } } void main() { throw new MyException; } Then I get the desired behaviour: $ dmd except.d $ ./except except.MyException@except.d(2) This is too tortuous, and methinks a mixin is in order, and since I can't do anything like the C preprocessor's #X stringizing, I can't declare this as a mixin template but have to do a string mixin: $ cat myexception.d string ExceptionDeclaration(string newExceptionName, string baseExceptionName = "Exception") { return "class " ~ newExceptionName ~ ": " ~ baseExceptionName ~ `{ this(string msg = "", string file = __FILE__, size_t line = __LINE__) { super(msg, file, line); } }`; } void main() { mixin(ExceptionDeclaration("MeaCulpa")); try { throw new MeaCulpa; } catch (MeaCulpa e) {} import std.conv; mixin(ExceptionDeclaration("MeaNeueaCulpa", "ConvException")); try { throw new MeaNeueaCulpa; } catch (MeaNeueaCulpa e) {} throw new MeaNeueaCulpa; } $ dmd myexception.d $ ./myexception myexception.main.MeaNeueaCulpa@myexception.d(18) ... So, any thoughts? Any way this could be improved? Would be nice if that mixin got into the standard library somehow...