Is there any way to go about making derived Exception classes which produce a passed error message plus a hard-coded annotation string provided by the derived class, allowing me to use both a consistent error message suffix plus a programmer-specified error message?
I'm running into a problem where I want to create a set of Exception classes that automatically annotate Exception calls based on the class of the Exception, ensuring a more rigid syntax, avoiding typos and/or having to remember to identify the .
In my (barebones) production code, I currently have:
throw new Exception("vec3.bearing (NotYetImplemented)");
but I would vastly prefer that to be:
throw new NotYetImplementedException("vec3.bearing");
which offers code completion, typo safety, consistency, a toolbox of recommended exception types if I ever stop being the sole programmer, etc. (Still nothing I can do to pull the name of the current function and include that automatically (I think?), since the best I've got is __LINE__
etc. But we can't all eat pure syntactic sugar or we'd die of code-abetes.)
Now, https://github.com/dlang/druntime/blob/master/src/object.d clearly expresses that the constructors of Exception are @nogc. Therein lies the problem: there is no way to use the ~ concatenation operator in a @nogc function. At least at my current level of understanding of D (versus my background in C# where this is trivial), I can't think of any other way to pass a pure/nogc pair of strings that won't trip up the safety parameters.
Just as a raw test case, I tried the following:
https://run.dlang.io/is/VmCKwV
(where classes derived from MyException would then override the annotation function accordingly, avoiding the @safe limitation of global/static variables) and, sure enough, it didn't work -- as I anticipated it wouldn't.
I do get the reason why the Exception class is @nogc, as you can't necessarily rely on the memory state when an Exception is thrown. If it wasn't memory-safe, it would be possible to enter a state where the Exception explaining why the program is failing won't be produced when the program fails because it too fails, making it even harder to figure out the problem. But given that the substantial majority of manually thrown exceptions do consist of program states that aren't out of memory, it also limits my usage case.
I'm going to be digging around Phobos to see if I can mishmash something out of the stringizing functions, but that seems convoluted when a string concatenation "intuitively" should work, even though it obviously doesn't.
Has anyone else worked through this problem before and come up with a more elegant solution? Am I just over-analyzing the problem?