adr-4: deferred
deferred 2023-12-30

Subject

Patterns and guidance to build consistent Exceptions with useful reporting and debugging information

Decision

In general, Letterbook has a set of application-defined Exceptions that all inherit from Letterbook.Core.CoreException. In addition, these exceptions should use a builder pattern to facilitate collecting extra information and including it in a standard way on our Exceptions.

Impact

Context

We've started doing this a little bit already, but it's valuable to write down the decision. For example, Letterbook.Core.CoreException implements the builder pattern, as well as sets up some error flags.

The builders all make use of [Caller*] attributes on the builder method arguments. These attributes cause the compiler to replace default values with a computed compile time constant. This allows us to collect information about the calling site of these methods statically, and with no performance cost. That way we can record the method and location where these builders are called from. That's a lot easier than trying to intercept and examine a stack trace, and faster than using reflection to get the information.

This guidance is meant to be in keeping with Microsoft's recommended best practices. See the docs here https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions#in-custom-exceptions-provide-additional-properties-as-needed

Discussion

This ADR is as much to collect discussions about help ourselves in the future with good error reporting as it is to codify this specific practice. Any suggestion or feedback is welcome.