Having Single and SingleOrDefault to throw a more succinct exception

May this solve the problem?

public virtual Fee GetFeeByPromoCode(string promoCode)
{
    try
    {
        return _fees.SingleOrDefault(f =>
            {
                try
                {
                    return f.IsPromoCodeValid(promoCode);
                }
                catch(InvalidOperationException)
                {
                    throw new PromoCodeException();
                }
            });
    }
    catch (InvalidOperationException)
    {
        throw new TooManyFeesException();
    }
}

I consider First() / Single() / SingleOrDefault() as a kind of Assert.

i.e. If you use them you don't want to catch the exception. Something is very wrong with your data and it should be handled as a critical error.

If multiple results is normal in your model, don't use exceptions to verify it.

From that perspective I don't think your Take(2) version is less obvious.