Search code examples
c#.net-coreneo4jgraph-databasesneo4jclient

How to resolve "Neo4j returned a valid response, however Neo4jClient was unable to deserialize into the object structure you supplied." error?


I am using neo4jclient graph database with .net core API. I have to add the health checks. I have created my own health check using Ihealthcheck interface. below is my healthcheck class

public class DatabaseHealthCheck : IHealthCheck

{
    public DatabaseHealthCheck(IGraphClient graphClient)
    {
        _graphClient = graphClient;
    }

    private readonly IGraphClient _graphClient;
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))

    {
        try
        {
            var result = await _graphClient.Cypher.Match(@"show databases")
            .Return((n) => n.As<DatabaseDetail>()).ResultsAsync;

            foreach (var res in result)
            {
                if (res.currentStatus == "Online")
                {
                    return await Task.FromResult(
                           HealthCheckResult.Healthy("Healthy"));
                }
            }
        }

        catch (Exception ex)
        {
            return new HealthCheckResult(status: context.Registration.FailureStatus, exception: ex);
        }

        return HealthCheckResult.Healthy();

        //    return await Task.FromResult(
        //        new HealthCheckResult(context.Registration.FailureStatus,
        //        "Unhealthy"));
    }
}

With this health check I want to get the database details and then check the status of database weather it is online or not but I am getting the below error

Neo4j returned a valid response, however Neo4jClient was unable to deserialize into the object structure you supplied.

Can anyone help me ?


Solution

  • The query you're writing will not return anything, what you're actually executing is:

    MATCH (show databases)
    RETURN n
    

    You can see this if you change your code to look like this:

    var query = _graphClient.Cypher.Match(@"show databases")
               .Return((n) => n.As<string>());
               
    var text = query.Query.DebugQueryText;
    var result = await query.ResultsAsync;
    

    If you put a breakpoint in so you can see what the text variable will be you'll be able to see it.

    Now! I can't think how to get what you want when you're using the GraphClient - it might be possible with the BoltGraphClient - but the error you're getting implies you're using the former.

    IF you were on the BoltGraphClient, you could access the Driver and execute:

    var session = ((BoltGraphClient)_graphClient).Driver.AsyncSession(d => d.WithDatabase("system"));
    var cursor = await session.RunAsync("SHOW DATABASES");
    while (await cursor.FetchAsync())
    {
        var name = cursor.Current.Values["name"].As<string>();
        var status = cursor.Current.Values["currentStatus"].As<string>();
        Console.WriteLine($"{name} is {status.ToUpperInvariant()}");
    }
    

    I don't know any other work around with the http GraphClient - it would need to be added to the client. In theory - it's not a complex PR to do if you wanted to.