Functional C#: Handling failures, input errors

By Vladimir Khorikov

The topic described in this article is a part of my Applying Functional Principles in C# Pluralsight course.

In this article, I’m going to write about how to deal with failures and invalid input in a functional way.

Handling errors in C#: the common approach

The concept of validation and error processing is well known, but the code required to handle it may become really annoying in languages like C#. This article is inspired by Railway Oriented Programming which was introduced by Scott Wlaschin in his talk at NDC Oslo. I encourage you to watch the full video as it gives invaluable insights of how awkward our day-to-day C# code might be.

Look at the sample below:

[HttpPost]

public HttpResponseMessage CreateCustomer(string name, string billingInfo)

{

    Customer customer = new Customer(name);

 

    _repository.Save(customer);

 

    _paymentGateway.ChargeCommission(billingInfo);

 

    _emailSender.SendGreetings(name);

 

    return new HttpResponseMessage(HttpStatusCode.OK);

}

It seems easy and straightforward: first we create a customer instance, then save it, after that charge some commission and finally send a greetings e-mail. The problem with this code is that it handles the happy path only, i.e. the path in which everything goes just fine.

When you start taking into account potential failures, input errors and logging routine, the method starts turning into boilerplate code:

[HttpPost]

public HttpResponseMessage CreateCustomer(string name, string billingInfo)

{

    Result<CustomerName> customerNameResult = CustomerName.Create(name);

    if (customerNameResult.Failure)

    {

        _logger.Log(customerNameResult.Error);

        return Error(customerNameResult.Error);

    }

 

    Result<BillingInfo> billingInfoResult = BillingInfo.Create(billingInfo);

    if (billingInfoResult.Failure)

    {

        _logger.Log(billingInfoResult.Error);

        return Error(billingInfoResult.Error);

    }

 

    Customer customer = new Customer(customerNameResult.Value);

 

    try

    {

        _repository.Save(customer);

    }

    catch (SqlException)

    {

        _logger.Log(“Unable to connect to database”);

        return Error(“Unable to connect to database”);

    }

 

    _paymentGateway.ChargeCommission(billingInfoResult.Value);

 

    _emailSender.SendGreetings(customerNameResult.Value);

 

    return new HttpResponseMessage(HttpStatusCode.OK);

}

Even worse, if we need to handle failures in both Save and ChargeCommission methods, we end up creating compensation logic so that the changes could be rolled back if one of the methods fails:

[HttpPost]

public HttpResponseMessage CreateCustomer(string name, string billingInfo)

{

    Result<CustomerName> customerNameResult = CustomerName.Create(name);

    if (customerNameResult.Failure)

    {

        _logger.Log(customerNameResult.Error);

        return Error(customerNameResult.Error);

    }

 

    Result<BillingInfo> billingIntoResult = BillingInfo.Create(billingInfo);

    if (billingIntoResult.Failure)

    {

        _logger.Log(billingIntoResult.Error);

        return Error(billingIntoResult.Error);

    }

 

    try

    {

        _paymentGateway.ChargeCommission(billingIntoResult.Value);

    }

    catch (FailureException)

    {

        _logger.Log(“Unable to connect to payment gateway”);

        return Error(“Unable to connect to payment gateway”);

    }

 

    Customer customer = new Customer(customerNameResult.Value);

    try

    {

        _repository.Save(customer);

    }

    catch (SqlException)

    {

        _paymentGateway.RollbackLastTransaction();

        _logger.Log(“Unable to connect to database”);

        return Error(“Unable to connect to database”);

    }

 

    _emailSender.SendGreetings(customerNameResult.Value);

 

    return new HttpResponseMessage(HttpStatusCode.OK);

}

You can see that our 5 lines have turned into 35 – the method has become 7 times longer! It is now really hard to follow the program flow. Those 5 lines of meaningful code are now buried under the bulk of boilerplate orchestration.

Handling failures and input errors in a functional way

Can it be fixed? Luckily, yes. Let’s go through the method and see what we can do with it.

You might have noticed that we use the technique I described in my primitive obsession article: instead of using the raw name and billingInfo strings, we are wrapping them with CustomerName and BillingInfo classes. That gives us an opportunity to put all the relevant validation logic in one place and comply with the DRY principle.

The static Create method returns a special class named Result which encapsulates all information regarding the operation’s results: an error message in case it failed and an object instance in case it succeeded.

Also, note that potential failures are wrapped with try/catch statement. Such approach breaks one of the best practices I wrote about in my Exceptions for flow control post. It states that if you know how to deal with exceptions, catch them at the lowest level possible.

It means that ChargeCommission and Save methods should catch known exceptions by themselves and return a result just as the static Create methods do. Let’s refactor the code:

[HttpPost]

public HttpResponseMessage CreateCustomer(string name, string billingInfo)

{

    Result<CustomerName> customerNameResult = CustomerName.Create(name);

    if (customerNameResult.Failure)

    {

        _logger.Log(customerNameResult.Error);

        return Error(customerNameResult.Error);

    }

 

    Result<BillingInfo> billingIntoResult = BillingInfo.Create(billingInfo);

    if (billingIntoResult.Failure)

    {

        _logger.Log(billingIntoResult.Error);

        return Error(billingIntoResult.Error);

    }

 

    Result chargeResult = _paymentGateway.ChargeCommission(billingIntoResult.Value);

    if (chargeResult.Failure)

    {

        _logger.Log(chargeResult.Error);

        return Error(chargeResult.Error);

    }

 

    Customer customer = new Customer(customerNameResult.Value);

    Result saveResult = _repository.Save(customer);

    if (saveResult.Failure)

    {

        _paymentGateway.RollbackLastTransaction();

        _logger.Log(saveResult.Error);

        return Error(saveResult.Error);

    }

 

    _emailSender.SendGreetings(customerNameResult.Value);

 

    return new HttpResponseMessage(HttpStatusCode.OK);

}

As you can see, now both ChargeCommission and Save methods return Result objects.

The goal of the Result class is pretty simple and very similar to the Maybe monad we discussed earlier: it allows us to reason about the code without looking into the implementation details. Here’s how it looks like (I omitted some details for brevity):

public class Result

{

    public bool Success { get; private set; }

    public string Error { get; private set; }

    public bool Failure { /* … */ }

 

    protected Result(bool success, string error) { /* … */ }

 

    public static Result Fail(string message) { /* … */ }

 

    public static Result<T> Ok<T>(T value) {  /* … */ }

}

 

public class Result<T> : Result

{

    public T Value { get; set; }

 

    protected internal Result(T value, bool success, string error)

        : base(success, error)

    {

        /* … */

    }

}

Now, we can apply the same principle that functional languages use. That is where the actual magic happens:

[HttpPost]

public HttpResponseMessage CreateCustomer(string name, string billingInfo)

{

    Result<BillingInfo> billingInfoResult = BillingInfo.Create(billingInfo);

    Result<CustomerName> customerNameResult = CustomerName.Create(name);

 

    return Result.Combine(billingInfoResult, customerNameResult)

        .OnSuccess(() => _paymentGateway.ChargeCommission(billingInfoResult.Value))

        .OnSuccess(() => new Customer(customerNameResult.Value))

        .OnSuccess(

            customer => _repository.Save(customer)

                .OnFailure(() => _paymentGateway.RollbackLastTransaction())

        )

        .OnSuccess(() => _emailSender.SendGreetings(customerNameResult.Value))

        .OnBoth(result => Log(result))

        .OnBoth(result => CreateResponseMessage(result));

}

 

If you are familiar with functional languages, you might have noticed that OnSuccess extension method is actually a Bind method. I named it that way just to make it clear how exactly it works.

What the OnSuccess method basically does is it checks the previous Result instance and if it is successful, executes the delegate passed in; otherwise, it just returns the previous result. Thus, the chain continues right until one of the operations fails. And if it does, the other operations are getting skipped.

OnFailure method, as you might guessed, is executed only if the previous operation failed. It is a perfect fit for the compensation logic we need to perform in case the database call wasn’t successful.

OnBoth is placed at the end of the chain. It’s main use cases are logging the operations’ failure and creating the resulting messages.

So what we got here is the exact same behavior we had before but with much less of boilerplate code. As you can see, the program flow has become much easier to follow.

What about the CQS principle?

What about the Command-Query Separation principle? The approach described above implies using return value (which is, in our case, an instance of the Result class) even if the method itself is a command (i.e. changes the object’s state). Is there a conflict with CQS?

No, there isn’t. Moreover, this approach increases readability in the same way following the CQS principle does. Not only does it allow you to know if a method is a command or a query, but it also allows you to see whether or not the method may fail.

Designing for failures extends the potential range of information you get from the method’s signature. Instead of 2 results (void for commands and some type for queries) you now have 4 of them.

  • The method is a command and it can’t fail:

    public void Save(Customer customer)

 

  • The method is a query and it can’t fail:

    public Customer GetById(long id)

 

  • The method is a command and it can fail:

    public Result Save(Customer customer)

 

  • The method is a query and it can fail

    public Result<Customer> GetById(long id)

 

And when I write that a method can’t fail I don’t mean it can’t fail in any given circumstances. Of course, there always is a chance of getting some kind of exception that wasn’t expected in the first place. What I mean is that the method is designed to always succeed, i.e. the developer supposes that any exception thrown within that method is unexpected (see also Exceptions for flow control in C# article for more details about expected and unexpected exceptions).

With this approach, exceptions become the thing they were intended to be initially: they signalize that there’s something wrong with your system. From that moment, they become a really helpful assistant on the way of building software.

Summary

Exposing your intent is crucial if you want to increase readability of your code. Introducing the Result class helps to show if the method can fail or not. OnSuccess, OnFailure, and OnBoth methods, on the other hand, help you remove boilerplate code resulting in a clean and narrow design.

In conjunction with other 3 techniques – immutability, getting rid of primitive obsession and non-nullable reference types – this approach introduces a powerful programming model that can significantly increase your productivity.

Source code

Source code for the Result, ResultExtensions classes and the usage example

Update

I’ve created a NuGet package out of the Result class and the extensions that work on top of it: link. If you want to request an addition of overloads to support your use cases, leave a comment here.

Other articles in the series

LinkedInRedditTumblrBufferPocketShare




  • Anders Baumann
    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks! It was an interesting read!

  • Eric Lubisse

    Nice stuff and well explained. I will look to use this immediately.

    • Eric Lubisse

      Perhaps not as elegant as the f# (or equivalent) would have been but readable and certainly better than the original C# code.

      • http://enterprisecraftsmanship.com/ Vladimir Khorikov

        Thank you!
        Yeah, F# code is more readable to me as well. But at least we are a little bit closer to it with this approach.

  • Brendon Reed

    You ever find using a string for the failure side too limiting? Form validation is a case where a list of errors can be nice, and I’ve had various cases where I want to return some other information with the error.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Yeah, I have. Although in most cases a single error message is just good enough, in case of multiple simple validations (checks for email, customer name, billing info validity), it’s better to have a list of errors.

      In such case, you can do something similar to the following:
      https://gist.github.com/vkhorikov/7df31ddd7bdc066623c4

      That way, you are able to gather all information about the errors happened within an operation and still preserve the functional error handling flow. Methods with side effects will be executed only if all of the side-effect free validations are passed.

      As for additional information with the error, unfortunately, in C# (unlike F#) it’s really tedious to do that. I personally tend to just include that info in the error string.

      Also, you might want to replace the string with an enum value for localization purposes (or just because it’d be a cleaner way to do that). I found that in simple projects, it’s not necessary, but could be a justified decision in more complex ones.

      • Brendon Reed

        Which part have you found really tedious? I tried switching the error type to a custom object so that I could override it when needed, but ended up disliking that because the simple usages get messier.

        I tried switching the error from a string to a generic type, and found that it really clutters up the simple usages, which is the majority of them, but was thinking maybe it’s not so bad. The creation of a separate error type just to return a bit of data is indeed a bit tedious, but it’s not very often, so it might be nice to have that ability. I thought about including it in the string, but matching on the string text, then parsing out a value just feels terrible.

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          If you need to use those data not just for presenting it to a user as a part of an error message, strings as an error object is indeed a terrible idea.

          The tedious part here is that in order to make it “right”, you need to introduce a hierarchy of different error types, which complicates the overall solution. In your case, it might be the only way to do that, though, so I think you should go ahead and try it.

          In terms of implementation, I’d start with something like this:
          https://gist.github.com/vkhorikov/552f106a9a2ca131be0b

          And update the Result class so that it accepts an Error class. The key here is to overload the most commonly used Result’s methods so that you continue working with strings in simple cases.

          • Brendon Reed

            Thanks, that’s the direction I’m heading.

          • http://www.bakins-bits.com David Bakin

            Another option is to use an Exception as the error data. It has a type (which can indicate the error, just like a specific enum), it has a message which is an arbitrary string, you can have more than one in your Result (by chaining via the inner exception), and it can have arbitrary data attached (via the Data property) that you can use later to format a better overall message or for other purposes.

  • http://www.bakins-bits.com David Bakin

    Very nice discussion and class. I have one question and one comment:
    Q: In your sources you’ve written OnSuccess(), OnFailure(), OnBoth() as extension methods? Why? (You control the source to Result, why not just make them methods of the class?)
    Comment: I have oft thought that a failure of C-like languages (including the O-O variants like C# and Java) is that allows dropping return values without error or even warning. I would like to have variant languages (compiler switches?) that gave errors if you dropped return values without either casting the method to void or wrapping the method call in a one argument method that returns void (perhaps provided in the language’s library.) This could apply to all functions/methods (I don’t see why not) or perhaps would be indicated at the function/method declaration by a keyword or annotation (or other syntax). How do you respond to the argument that this style of programming – returning a success/error value, even one with great monadish syntax, in a non-functional language, leads to errors where the programmer (inadvertently, perhaps) ignores the return value, as opposed to using exceptions to signal errors (especially, in Java, checked exceptions)?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks for your comment!

      Indeed, no need to create extension methods here, I should have added them as regular ones.

      Regarding your comment: that’s a perfectly accurate observation, in my opinion. I think that’s the reason why this style of programming traditionally isn’t popular among the C-like languages. If we had compiler telling us about the ignored returning values (just as it does in F#, forcing us to use the “ignore” function), the use of return values instead of exceptions would be more appealing for many.

      • David Raab

        I don’t think that the “ignore” function is what David Bakin means. With ignoring the error he basically means that you are not forced to check for an error. In your design it is the same. As your Result type is open it means you always can just access the Value directly and you never have to check the Success or Failure property of your Result class.

        But this is different in a functional language like F#. Because F# has Discriminated Unions and the Pattern Matching forces us to check every case we can create a Result Type and a developer is forced to check if he had a Success or Failure. Otherwise we get a compile-time error if we don’t do that.

        You can fix that by removing the Success, Failure and Value Property and only have let’s say a “Match” method that expects two lambdas one for the success and on for the Failure case. You also can create helpers like your OnSuccess that passes a Failure just through. But i still think this style of programing is sadly still very uncommon in OO languages.

        At least in C# things like that are not so uncommon. That is thanks to LINQ that now nearly exists since 10 years in C# and people now learned those things and see them as common. But most other languages either still don’t support that, or they are still new. For example what is LINQ in C# is Stream in Java, and it is still “new” in Java land, and most people still don’t accept stuff as Stream as common.

      • http://www.bakins-bits.com David Bakin

        BTW, this gist is the java class I wrote which was inspired by this blog post and your source code. Works great!

  • Christopher Andrews

    The article was extremely helpful, thank you. I found this .net error tracking tool amazingly simple and nice http://www.redfly.io

  • BoeseB

    Great post, i was looking into using monad like classes in C# a while now and really like the idea. With your series on functional c# i was finally able to find a good way how to use them for input validation.

    After looking at your Result implementation i wondered if there is a way to implement the whole thing just with structs, i dunno if there is any noteable advantage in it, but i would love to hear your opinion about it. Here is the implementation using structs instead of classes: https://gist.github.com/BoeseB/6c465bc8faaac5541449

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks!

      The only reason I used classes here is because I wanted to remove some code duplication between Result and Result of T by inheriting the latter from the former. It’s not possible to implement it with structs because they don’t support inheritance.

      The duplication itself it not substantial here, though, so I think the benefits of having structs instead of classes might indeed overweight the drawbacks of repeating a couple lines of code, especially in high-performant scenarios.

  • Amir Shitrit

    Isn’t having a Result class with an Exception field the same as the Task class (which also has ContinueWith + various overloads similar to OnSuccess and OnFailure)?

    Also, when using this approach of error handling, don’t I loose the advantages offered by SEH, such as multiple catch blocks with fallbacks?

    And for last, in case the Save method fails on an SqlException, it could be a network failure or some other technical problem, in which case shouldn’t we consider this failure to be unexpected? I would think that domain-level errors (e.g. validation, concurrency, consistency, and other business rules) should be considered as expected exceptions…

    Thanks,
    Amir

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Isn’t having a Result class with an Exception field the same as the Task class (which also has ContinueWith + various overloads similar to OnSuccess and OnFailure)?

      I wouldn’t conflate them. Task relies on exceptions to determine its successfulness, whereas the idea with Result is to depart from using exceptions for controlling the program flow entirely.

      Also, when using this approach of error handling, don’t I loose the advantages offered by SEH, such as multiple catch blocks with fallbacks?

      What’s SEH? Not sure I’m familiar with this abbreviation.

      And for last, in case the Save method fails on an SqlException, it could be a network failure or some other technical problem, in which case shouldn’t we consider this failure to be unexpected?

      Yes, to convert an exception into a Result object, you need to drill into the exception details deep enough to make sure that exception is the one expect. In practice, it means that along with specifying its type, you need to also analyze the message coming with it and sometimes inner exceptions as well.

      • Amir Shitrit

        “I wouldn’t conflate them. Task relies on exceptions to determine its successfulness, whereas the idea with Result is to depart from using exceptions for controlling the program flow entirely.”

        [Amir] I agree. But do you think it would make sense to through an exception in case the developer accesses the Result.Value property without checking first for success?

        This would eliminate the problem of developers ignoring return values for non-void results.

        SEH = Structured Exception Handling. I was referring mainly to the ability to use multiple catch blocks..

        Regarding drilling down on exceptions, sometimes we have an error code (as in SqlException and HttpException), in which case there’s no need to drill down.

        On other cases, I agree that it can become pretty cumbersome…

        Thanks!

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Yes, it definitely makes sense to throw an exception if a client code accesses Result.Value and that value doesn’t exists due to an operation failure. I didn’t emphasize it in the article, but I’ve actually added such a check to the Result class: https://gist.github.com/vkhorikov/7852c7606f27c52bc288#file-result-cs-L61 Here, a violation of a contract would result in an exception.

          Regarding SEH, it can be converted into an “if” or “switch” statement. So basically, instead of relying on the exception types, we can check the type of the error that comes with the Result object. Although, the Result implementation from this article probably wouldn’t be a good fit for that, you’ll need to use an Enum instead of a string to represent an error.

          Regarding drilling down on exceptions, sometimes we have an error code (as in SqlException and HttpException), in which case there’s no need to drill down.

          Yep, absolutely!

          This is overall a very interesting subject to discuss. I’m actually working on a Pluralsight course on this exact topic. As part of it, I’ll try to explain the reasoning behind using the Result class and compare it with the use of exceptions for that matter. Pretty much the same as discussed in this article but with more details.

    • http://sidburn.github.io/ David Raab

      Isn’t having a Result class with an Exception field the same as the Task class (which also has ContinueWith + various overloads similar to OnSuccess and OnFailure)?

      The idea of “Task” is also just a “Monad” like the provided “Result” type here. So yes they are some kind of the same. They share the same concept. But sure it doesn’t mean they do the same thing. Task tries to handle Asynchronous code, Result tries to handle errors.

      A more interesting thing is. Especially for validating i would prefer an “Applicative Functor” instead of a Monad. Because you are usually interested in all kind of validation errors. A Monad usually stops at the first validation error. Actually that leads to the question how you can implement an Applicative Functor in C#. I never have seen it (i think) and also don’t have a particular idea how to do it, well. It’s the first time even i think about this.

      Also, when using this approach of error handling, don’t I loose the advantages offered by SEH, such as multiple catch blocks with fallbacks?

      It just depends on the data-type you use. In F# you would use a Discriminated Union as an Error type and every error just has its own case. You can rebuild such a structure with some kind of a class hierarchy, simpler an enum. In the future you can use DU as they are planned with C# 7.

      should be considered as expected exceptions…

      Isn’t *expected* exceptions some kind of contradictory?

  • Michael G.

    We have an issue at work where one method iterates over a collection of objects, and performs an action on each of those objects. We want the caller of the method to know whether or not their call was a success, failure, or a partial success.

    Pseudo-code:
    —————
    Result ChargePendingPayments() {
    Payment[] collection = GetPendingPayments();

    foreach (payment in collection)
    {
    if (payment.Charge())
    // indicate success for this payment
    else
    // indicate failure for this payment
    }

    return new Result();
    }
    —————

    A few scenarios should be handled:
    — GetPendingPayments() fails = inform the caller of failure
    — All payments fail to charge = inform the caller of failure
    — All payments successfully charge = inform the caller of success
    — Some of the payments fail to charge = inform the caller which failed, and which succeeded

    Given the above:
    1. How would you model such a Result class?
    2. How would you indicate that only some of the payments failed?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      In this case, you would need to introduce a separate Error class hierarchy and enhance the Result class so that it holds not just a single string but a list of errors. So the Error property in Result will be changed from

      public string Error { get; private set; }

      to

      public IReadOnlyList Errors { get; private set; }

      Here’s an example of the Error class: https://gist.github.com/vkhorikov/552f106a9a2ca131be0b

      In your case, you can make a PaymentFailedError class which would inherit from Error and contain the data regarding which concrete payment has failed. This way, your error will convey enough information for the caller to make an informed decision regarding how to react to multiple payment failures.

      • Michael G.

        We went with an option where a specification of the Result class contains two collections: one for succeeded, and one for failed. This allows the caller to iterate through each collection to apply any necessary logic to each item respectively.

        While our solution does work, yours seem the better option by introducing an Error class to hold detailed information. In the future we will likely refactor the module as such.

        Thank you for your answer :)

  • Karl Gjertsen

    Just watched your PluralSight course, to implement this in a project I am working on.

    What do I do if I need to use a return value from one of the items in an OnSuccess and used it in the next call?

    Example:

    Function 2 returns a value that I want to include in the call to Function 3:

    Function1()
    .OnSuccess(() => Function2())
    .OnSuccess(() => Function3(param1))
    .OnBoth(result => AddtoLog(result));

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      You will need to add this overload: https://github.com/vkhorikov/CSharpFunctionalExtensions/blob/master/CSharpFunctionalExtensions/ResultExtensions.cs#L16 . Here’s a usage example: https://github.com/vkhorikov/CSharpFunctionalExtensions/blob/master/CSharpFunctionalExtensions.Examples/ResultExtensions/UsageExamples.cs#L15 .

      I’ve created a NuGet package so you can use it instead of manually adding overloads needed: http://enterprisecraftsmanship.com/2016/06/24/c-functional-extensions-nuget-library/

      Also, feel free to request new overloads, I’ll add them to the package as well.

      • Tahir Naushad

        Great article, course and code samples. One question related to passing parameters to “next” OnSucess, what if a step in the process requires output from multiple previous steps? There could be few options like passing PreviousResult within the Result so it forms a chain of Results. Also passing value/complex objects rather than simple types as input/output could work. Your thoughts would be much appreciated.

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Thank you! Working with multiple result instances is indeed not so smooth. I usually do something along these lines:


          Result customerName = CustomerName.Create(model.Name);
          Result primaryEmail = Email.Create(model.PrimaryEmail);
          Result industry = Industry.Get(model.Industry);

          Result combinedResult = Result.Combine(customerName, primaryEmail, industry);

          and then work with combinedResult from there.

          In terms of passing previous result instance to the next OnSuccess, you usually need the Result itself and not the wrapped value only with OnBoth methods, where you want to return the final response to the caller by examining that result. Delegates you pass into OnSuccess and OnFailure usually don’t need to operate on top of the raw Result instance, they just need the wrapped value itself.

  • Joseph Adjare

    I’m interested to hear how you feel this stacks up against the advice you give in the following post
    http://enterprisecraftsmanship.com/2016/09/13/validation-and-ddd/

    This advice, along with other blogs posts I’ve read, has led to me adopting a “CanDoOperation” style check prior to executing a command. The command can then raise an exception for any failure.

    I appreciate this post is in part about dealing with handling failures as well as input errors and the former is certainly not quite the same as dealing with validation. However, I’m wondering what your thoughts are on applying such an approach in failure handling, e.g.

    “`CSharp
    if(billingService.IsAvailable()) {
    billingService.CreditAccount(customer, amount);
    } else {
    logger.Log(“billing service not available”);
    }
    “`
    Such an approach as avoids the trap of the method caller failing to check the Result object for failures and ultimately having unforeseen errors occuring in the application without even realising.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      I usually prefer the “CanDoOperation” style too. My personal approach is mostly the same as in “Validation and DDD” (the last option) with the exception that I use the Result class in place of plain strings. Or if it’s just a simple yes/no answer, then I just use boolean.

      So, I tend to write the following checks:


      Result creditCheck = CanCredit(address);
      if (creditCheck.Succeeded)
      {
      Credit(address);
      }

      Inside Credit, there’s also another check like this:


      public void Credit(address)
      {
      if (CanCredit(address).Failed)
      throw new ContractException();

      /* ... */
      }

      Now, there are cases where the result of the check might be stale at the time of the actual operation. For example, you might check that the service is available but when you try to perform the operation, it goes down. It such situations there’s no other choice than embedding the check into the Credit method itself and returning Result instead of void.

      So, for input validations, I prefer “Execute / CanExecute” pattern. For failures – TryExecute one. I use terminology from the post you referenced: http://enterprisecraftsmanship.com/2016/09/13/validation-and-ddd/