You don't need to implement a custom description, or in fact anything.
String(describing:) gives you the description of a value if its type conforms to CustomStringConvertible or a suitable magical default otherwise.
String(reflecting:) gives you the debugDescription of a value if the type conforms to CustomDebugStringConvertible or a suitable magical default otherwise.
In this case, you want a description for debugging, and the compiler already gives you exactly what you want magically:
Ah. You can get just the portion of the debugging description for the type from String(reflecting: type(of: error)).
The specific case is part of the value and not part of the type, so of course if you are intent on customizing how the value is printed by conforming to CustomStringConvertible, you will have to provide that yourself (since, after all, that is the entire point of conforming to CustomStringConvertible), just as you must the labels for each associated value.
Let me ask this. Is there way to customize the "description" for a particular property only, rather than for an entire type? In this example I want to customize the description for reasonCode but not for returnCode.