Ingeniously Simple
Published in

Ingeniously Simple

Easy GDPR-safe exception messages with C# interpolated strings

How a brand new C# feature can help with safe, painless, detailed exception reporting.

Let’s say you’re writing an application that reads config files, and you need to handle errors:

This is largely sensible code, and it works. But what is a user supposed to do if they see an error message like “Failed to read config”? We can make the error a lot more helpful by providing detail:

Now this is much more likely to give the user a way to figure out what the problem is, and everyone is happy. But what happens when this exception ends up going other places as well?

If this exception is sent from a user’s machine, we need to start worrying about PII (personally-identifiable information) that could be part of the exception. If the exception contains PII, then it (and any data that can be correlated with it) becomes subject to the GDPR, or some equivalent local data protection laws. We want to avoid this unless it’s actually necessary.

In the above example, there’s two sources of PII that could become part of this exception: may contain users’ names (eg ) and the underlying exception could also contain arbitrary information which we don’t control.

So what can we do? We want users to have as much information as possible to diagnose the problem, but we want to avoid sending some of that information as an exception report.

The solution we came up with is : a type that wraps around , but contains both “safe” and “unsafe” values:

The idea is that we can construct one of these to hold our exception messages: the “unsafe value” may contain PII, but can be shown to users, while the “safe value” is fine to log or send to any remote monitoring services. We use in our application’s exception type, making sure that the base property only ever sees the safe value:

So this solves our problem pretty neatly. But you might have thought “aren’t all those s going to be a pain to construct? After all, now we have to specify every string twice!” And you’d be right!

Fortunately, a new C# 10 feature comes to the rescue. The basic idea is this: we know that any literal strings cannot contain any PII by definition, since they’re the same for every user. Variables and interpolated bits of strings, however, may be unsafe.

The C# feature is built around the new attribute. A class or struct marked with this attribute can become a method parameter:

and then that parameter can accept an interpolated string:

Note how we’re passing an interpolated string to , even though that method doesn’t accept a string. This is only possible because of the attribute.

What happens next is that the compiler changes our consuming code to something like this:

Now it’s up to us to define those methods on . We can define them any way we want, so long as the above code compiles:

We could have many overloads, or we could just define a single generic implementation that takes a and calls . It’s up to you :)

Anyway, the upshot is that we now only have to define our string once, and we’ll automatically get a value with both safe and unsafe values. This is a huge saving compared to having to write out every error message twice.

This is just one use I’ve found for custom interpolated string handlers in C# — I’m sure there are many more! I’d love to hear about any cool examples you might come up with.

Photo by Alexander Naglestad

--

--

How Redgate build ingeniously simple products, from inception to delivery.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store