Kevin Cruijssen
Kevin Cruijssen

Reputation: 9336

SingleOrDefault: Catch just "Sequence contains more than one element" InvalidOperationException

In our project we recently added an import tool for old data, in which we convert this old data to usable objects in our application. In this import we have the following piece of code:

using (var session = documentStore.OpenSession())
{
    try
    {
        var cluster = session.Query<ClusterState>().SingleOrDefault(x => x.Name == clusterString);
        return cluster != null
            ? (ClusterId) cluster.AggregateId
            : null;
    }
    catch (InvalidOperationException e)
    {
        if (String.Equals(e.Message, "Sequence contains more than one element"))
        {
            Logger.Warn("More than one cluster found with the given string: {0}", clusterString);
            if (...)
            {
                return ...
            }
            return null;
        }

        throw;
    }
}

My issue is the following line:

if (String.Equals(e.Message, "Sequence contains more than one element"))

It works local, but not on the server. The reason for this is we have a Dutch server, so instead of "Sequence contains more than one element" it gives a "Reeks bevat meerdere elementen" InvalidOperationException. Now I know I can modify the code to this:

if (String.Equals(e.Message, "Sequence contains more than one element")
    || String.Equals(e.Message, "Reeks bevat meerdere elementen"))

Of course this works, and I don't think we intend to have a different language server in the future, but still, it's pretty bad code and if the message ever changes with a new .NET / LINQ version, this doesn't work anymore.

So, is there any other way to catch just "Sequence contains more than one element" InvalidOperationException, and not any other InvalidOperationExceptions?

Should I add a Count check or something to see if I receive more than one matching element instead of the Try-Catch, or is there a distinguished way to filter just the "Sequence contains more than one element" Exceptions? Or should I just catch all "InvalidOperationExceptions" and add an additional log-line so we get notifications of these exceptions?

Upvotes: 1

Views: 1628

Answers (1)

Pranay Rana
Pranay Rana

Reputation: 176956

You can set culture of the program to en-US can resolve your problem

Example :

 // Change current culture
  CultureInfo culture;
  if (Thread.CurrentThread.CurrentCulture.Name == "fr-FR")
     culture = CultureInfo.CreateSpecificCulture("en-US");
  else
     culture = CultureInfo.CreateSpecificCulture("fr-FR");

  Thread.CurrentThread.CurrentCulture = culture;
  Thread.CurrentThread.CurrentUICulture = culture;

Create your extension method and raise your own exception as alternate solution

public static TSource SingleOnlyOrDefault<TSource>(this IEnumerable<TSource> source,
        Func<TSource, bool> predicate)
    {
        if (source == null) { throw new ArgumentNullException("source"); }
        if (predicate == null) { throw new   
                         ArgumentNullException("predicate");    
    }

    IEnumerable<TSource> matchingItems = source.Where(predicate);
    int matchedItemCount = matchingItems.Count;

        switch (matchedItemCount)
        {
            case 0: return default(TSource);
            case 1: return matchingItems[0]; // Or Single() 
            default: throw new Exception("Too many element exist for    condition");
        }
    }

Upvotes: 2

Related Questions