Value Objects and Error Messages

I haven’t done one of these for a while. This post is a review of a code submitted by a reader. You can request such a review by using the submission form in the right sidebar or on this page.

Value Objects and Error Messages

Below are the code and questions. Some parts of the code were in German, so I translated them into English. Hopefully, I didn’t lose any semantics. And if I did, it’s Google Translate’s fault 🙂

For all Value Objects, we used your base class and the following best practices: private constructor, static Factory method with invariant enforcement. We made a Value Object for each property with validation rules. The bad thing is that we have the name of the property hard-coded in our error message (‘Allowance’ in the code sample above).

For example, if we have properties

public AllowanceAmount Allowance1 { get; private set; }


public AllowanceAmount Allowance2 { get; private set; }

in the same entity, we don’t know exactly which Allowance is failed based on the error message. We create our Value Objects in the Application Layer (=our command handlers) and return the error messages from the domain layer to the client (Angular):

What do you think about Value Objects like Optional70LimitedString? There’s the same problem with it, the error message doesn’t include the property name. For example:

public Optional70LimitedString LastName { get; private set; }

Can you advice how to handle error messages from the domain layer? Should we display domain layer error messages (which Result object contains) in the UI or should we translate it?

I haven’t translated the second piece of code into English, but I think you get the idea: multiple Value Objects get created and validated, and you need to show the result of that validation to the client.

Here’s, by the way, the link to the Value Object base class I currently use on my projects: Value Object: a better implementation.

There are 3 questions in here:

  • How to map a specific validation error to the source of it, i.e. the name of the field the user made a mistake in?
  • Should you display the errors from the domain model as is or should you translate/transform them when displaying on the UI?
  • What do I think about Optional70LimitedString Value Object?

I’ve answered the last one in the previous blog post. In short: I don’t recommend using a Value Object with such a name because this name doesn’t belong to the ubiquitous language of the problem domain. Use names that can be traced to specific domain concepts instead, such as Password, Email, or AllowanceAmount.

The answer to the second question depends on your project. In most typical applications with JavaScript-based UI, it’s fine to use error messages from the API as is. There’s a quite tight coupling between such a UI and the API already anyway, and so there’s no need to decouple the validation errors from their descriptions.

It’s a different situation when you’ve got an API-to-API communication, though, such as that of microservices. In this case, you want to use an error code. The reason why is because the client API most likely won’t display that error to anyone. Instead, it will try to react to it, and for that, it needs to distinguish one type of error from another. A unique numeric identifier works better than a string here.

And even if the client API does need to show an error message to its users, it still needs to present that message in its own terms, using its own ubiquitous language. Numeric codes allow the client API to easily associate a specific error message with every type of error the server API may return. For example, if an Identity Server returns you a “ClientId is Invalid” error, you would probably want to represent it as something like “Invalid username or password. Please, try again” instead.

But again, in typical client-server applications, like with AngularJS as the client and ASP.NET as the server, the tight coupling between the two tiers in terms of the error messages is fine.

Mapping a validation error to its source

Alright, that brings us to the last (or, rather, first) question:

How to map a specific validation error to the source of it, i.e. the name of the field the user made a mistake in?

This question nails it. The single drawback of the approach with using Value Objects is that it complicates validation error handling in CRUD scenarios.

It’s easy to generate validation errors with an input model like this:

The attributes and the built-in ASP.NET validation mechanism will do all the work for you. This code:

magically results in proper validation errors on the UI.

How the hell are you going to do the same when all your validation logic is baked into the Value Objects and you are not allowed to use the validation attributes?

This is what a typical error handling code looks like when you are using Value Objects:

Note the absence of attributes on the customer model. They are discouraged because they would introduce duplication of the domain knowledge regarding what constitutes a valid allowance amount.

The drawback here is that there’s no way to track the error back to the specific allowance. The other inconvenience is that the API displays only one error at a time. If there are several errors, only the first one will be shown.

So, how to overcome this problem?

The original validation code that relies on ASP.NET produces the following JSON:

You can emulate the same behavior with a little bit of coding. This is what the solution could look like:

Here, we are combining the errors with their sources using LINQ expressions. Expressions help you avoid hard-coding field names so that when a property in the input model is renamed for some reason, the resulting JSON will reflect this change automatically.

Here’s what the new Create returns:

The result now contains the names of the properties that cause the validation error. And it also lists all those errors, not just the first one. Which is pretty neat.

Note that you don’t have to mimic the output of the ASP.NET validation mechanism. You are most likely parsing that output on the UI manually anyway, so it’s a good idea to come up a JSON structure that satisfies your specific needs. Create a custom envelope class that would contain either a list of errors or a result and use it across all your API endpoints. You can employ the above approach to populate that envelope with the detailed information about validation errors.

Alright, that’s it for today. If you want me to review your own code, send it over using the submit form on this page. Feel free to ask any questions too.

Reference list