Multiple asynchronous Cosmos DB queries resulting in "InvalidCastExceptions"

1

I have an Azure function app with multiple functions running within it. If multiple queries end up running at the same time, I get an InvalidCastException from deep inside of the DocumentQuery code. If I disable all but a single function (doesn't matter which), the error does not occur, leading me to believe there's some sort of shared memory issue going on.

I've removed everything with the exception of the problematic queries to attempt to isolate the issue, confirming that the issue indeed stems from >1 async calls to cosmos Db.

The issue seems to arise if I call DocumentQuery.ToString() or await DocumentQuery.ExecuteNextAsync() while another query is being evaluated. Specifically, all issues arise here:

public static async Task<List<T>> ToListAsync<T>(this IQueryable<T> source, QueryCase queryCase = QueryCase.CamelCase) where T : class
{
    var results = new List<T>();
    IDocumentQuery<T> documentQuery = source.ChangeCase(queryCase).AsDocumentQuery();

    while (documentQuery.HasMoreResults)
    {
        FeedResponse<T> queryResult = await documentQuery.ExecuteNextAsync<T>();
        results.AddRange(queryResult);
    }

    return results;
}

That ChangeCase() function calls DocumentQuery.ToString() and it'll fail there, and if I remove that, the failure will occur on ExecuteNextAsync()

Stack trace:

System.InvalidCastException
  HResult=0x80004002
  Message=Unable to cast object of type 'Newtonsoft.Json.Converters.StringEnumConverter' to type 'Newtonsoft.Json.JsonConverter'.
  Source=Microsoft.Azure.DocumentDB.Core
  StackTrace:
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.ApplyCustomConverters(Expression left, SqlLiteralScalarExpression right)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitBinary(BinaryExpression inputExpression, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitScalarExpression(Expression inputExpression, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitScalarLambda(Expression inputExpression, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitWhere(ReadOnlyCollection`1 arguments, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitMethodCall(MethodCallExpression inputExpression, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.Translate(Expression inputExpression, TranslationContext context)
   at Microsoft.Azure.Documents.Linq.ExpressionToSql.TranslateQuery(Expression inputExpression)
   at Microsoft.Azure.Documents.Linq.SqlTranslator.TranslateQuery(Expression inputExpression)
   at Microsoft.Azure.Documents.Linq.DocumentQueryEvaluator.HandleMethodCallExpression(MethodCallExpression expression)
   at Microsoft.Azure.Documents.Linq.DocumentQueryEvaluator.Evaluate(Expression expression)
   at Microsoft.Azure.Documents.Linq.DocumentQuery`1.ToString()
   at Api.Data.Extensions.DocumentDBLinqExtensions.ChangeCase[T](IQueryable`1 query, QueryCase queryCase) in C:\Users\jason\source\repos\HeroPlatform\HeroPlatform\Api.Data\Extensions\DocumentDbLinqExtensions.cs:line 138

EDIT: I have discovered that removing [JsonConverter(typeof(StringEnumConverter))] from the top of an enum I am using in the query resolves the error (although now my data is trying to query enums by number instead of string).

I actually don't seem to have a cosmos DB extension version added in any project in the solution. I am creating an IServiceCollection and supplying it with the following DocumentClient:

new DocumentClient(
        new Uri(configuration["DocumentDb:EndpointUri"]),
        configuration["DocumentDb:Key"],
        serializerSettings: GlobalJson.SerializerSettings(),
        connectionPolicy: new ConnectionPolicy()
        {
            MaxConnectionLimit = 100,
            ConnectionMode = ConnectionMode.Direct,
            ConnectionProtocol = Protocol.Tcp,
        }))

GlobalJson.SerializerSettings()

var serializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCaseExceptDictionaryKeysResolver(),
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
                DateParseHandling = DateParseHandling.DateTimeOffset,
                DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
            };
            serializerSettings.Converters.Add(new StringEnumConverter());

            return serializerSettings;
c#
azure
azure-functions
azure-cosmosdb
asked on Stack Overflow Apr 23, 2019 by GravlLift • edited Apr 25, 2019 by Tony Ju

1 Answer

1

This is regression. Here is the tracking issue https://github.com/Azure/Azure-Functions/issues/1201 . Please pin Functions Runtime version to 2.0.12382

answered on Stack Overflow Apr 23, 2019 by Pragna Gopa

User contributions licensed under CC BY-SA 3.0