If we cast back our thoughts back to the start of this series, one of the limitations of using string to return each of our errors was that every message has to be an error. What do we do if we want to support another kind of message?
To illustrate, let’s extend our system with a warning - a non-fatal message.
Before we look at the code, where would a warning be used? Here are two examples.
In a parts inventory system, someone will have the ability to change the unique part number used for a product - we can’t have a system where correcting an error is impossible. But, such a change has an extremely wide impact - it shouldn’t happen casually. It can be useful to show a warning when this happens as a hedge against unintended consequences: All users will need to use the new part number, effective start of business tomorrow.
Or you might have a promotional system where each marketing campaign has start and end dates. Sometimes it’s necessary** to modify the dates of a campaign that’s already underway - but it’s not something to do lightly. A warning to remind the user that the campaign is live can be a useful safety net to prevent unexpected changes (as when they think they’re changing the *next campaign, not the current one).
With the semantic type approach we’ve developed so far, we can add support for warnings by introducing a new descendant of
Validation class gets extended with add new factory methods:
ValidationResult class needs to be modified to allow access to the warnings. One approach would be to parallel the approach taken for errors by adding members:
An alternative would be to rename
Results and rely on consumers checking the type of each item:
However, back in the earlier post on type recovery we talked about the desirability of avoiding such boilerplate.
For this series, I’ll go with the former approach, adding
HasWarnings. The implementaitons for these are very simple for the most part; here’s how it works for
AggregateResult, the most complex case:
The last piece of the puzzle is to implement the
Add() method so that our
+ operator works properly. We’ll follow the existing pattern - a success value disppears, leaving a warning intact; otherwise we don’t want to drop any results.
WarningResult, the implementation looks like this:
Don’t forget that the other implementations of
Plus() need to be extended to handle a
WarningResult as well. They’re pretty straightforward, so I’m leaving those as an exercise for the reader.