Refactoring away from throwing exceptions in c#
let’s see the simple example and show what is the problem
This example is very simple to CreateEmployee and saves in the database but before add in the database we should validate the name of the Employee, problem here
- The validate name method is dishonest (you can’t know the outcome of this method by looking at the signature of this, you must go to the implementation to know what is output.
- you don’t have the control flow that each method call these function must wrap with try/catch block
To refactor this code we put all the output in the signature of the method by returning the validation error.
Always prefer using return values over exceptions.
Use Cases for Exceptions:- Exceptions are for exceptional situations, Exceptions should signalize a bug, Don’t use exceptions in situations you expect to happen you expect that the user may enter invalid data.
Where to Catch Exceptions :
- Should be caught at the lowest level possible
- The highest level possible for logging purposes
- Catch only exceptions you know how to handle
- Use return values to define an expected failure
you can improve the readability of the code by using Result design pattern by steve smith or create your own Result Class
The method is still dishonest we will discuss why is dishonest by avoiding primitive obsession.
Avoiding Primitive Obsession
Primitive obsession stands for using primitive types for domain modeling.
Drawbacks of Primitive Obsession
let’s see our simple example to see where is the problem
The problem here is the createUser method is dishonest because the method signature that takes any string and return the user but if the user inserts an invalid email it will throw an exception the signature of the method doesn’t tell anything about this. another problem of this code is code duplication if another domain model uses the concept of the email you will write and repeat all this code like this
and this code violates the dry (don’t repeat yourself principle ) you repeat your code two reasons to not use Primitive Obsession
- Dishonest
- Violate Dry
to get rid of Primitive Obsession you can use Value Object you can read more about Value Object ,now we create our value object class
now refactor our code to use the Email value object and use Result instead of throwing an exception.
Now
Removed validation logic duplications .
Created a single authoritative source of the domain knowledge .
Method signature honesty Stronger type system .
No need to validate values passed in.
the purpose of this article is to make our code more functional
Same input — same result, Information about possible inputs and outcomes.
you can see the Applying Functional Principles in C# by Vladimir khorikov