diff --git a/.github/workflows/integration-jobs.yml b/.github/workflows/integration-jobs.yml index a48076529a2..9c075b05dee 100644 --- a/.github/workflows/integration-jobs.yml +++ b/.github/workflows/integration-jobs.yml @@ -27,7 +27,8 @@ jobs: '8.3.3', '8.4.3', "8.5.3", - '8.6.0-SNAPSHOT', + '8.6.1', + "8.7.0-SNAPSHOT" 'latest-8' ] diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs index aebec65ae42..06f503d1e55 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs @@ -40,32 +40,32 @@ private sealed class ResponseItemConverter : JsonConverter>(ref readerCopy, options); + var result = JsonSerializer.Deserialize(ref reader, options); - // If we have a version number, we can be sure this isn't an error - if (result is not null && result.Version is not null) + if (result is not null && result.Error is not null) { - reader = readerCopy; // Ensure we swap the reader to reflect the data we have consumed. return new MultiGetResponseItem(result); } } catch (Exception ex) { - getResultException = ex; + errorException = ex; } try { - var result = JsonSerializer.Deserialize(ref reader, options); + var result = JsonSerializer.Deserialize>(ref readerCopy, options); - if (result is not null && result.Error is not null) + // If we have a version number, we can be sure this isn't an error + if (result is not null) { + reader = readerCopy; // Ensure we swap the reader to reflect the data we have consumed. return new MultiGetResponseItem(result); } } catch (Exception ex) { - errorException = ex; + getResultException = ex; } Exception innerException = null; diff --git a/tests/Tests/Document/Multiple/MGet/MGetResponseSerialization.cs b/tests/Tests/Document/Multiple/MGet/MGetResponseSerialization.cs new file mode 100644 index 00000000000..85ceb50b577 --- /dev/null +++ b/tests/Tests/Document/Multiple/MGet/MGetResponseSerialization.cs @@ -0,0 +1,63 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using Tests.Serialization; +using Xunit; + +namespace Tests.Document.Multiple.MGet; + +public class MGetResponseSerialization : SerializerTestBase +{ + private const string ResponseJson = @"{ + ""docs"": [ + { + ""_index"": ""foos"", + ""_id"": ""001"", + ""_version"": 5, + ""_seq_no"": 8, + ""_primary_term"": 1, + ""found"": true, + ""_source"": { + ""id"": ""001"", + ""name"": ""FooA"" + } + }, + { + ""_index"": ""foos"", + ""_id"": ""002"", + ""_version"": 5, + ""_seq_no"": 9, + ""_primary_term"": 1, + ""found"": true, + ""_source"": { + ""id"": ""002"", + ""name"": ""FooB"" + } + }, + { + ""_index"": ""foos"", + ""_id"": ""nonexistant"", + ""found"": false + } + ] +}"; + + [U] + public void MultiGetResponse_DeserializesCorrectly_WhenIdsAreNotFound() + { + var response = DeserializeJsonString>(ResponseJson); + + response.Docs.Should().HaveCount(3); + response.Docs.ElementAt(0).Match(r => r.Found.Should().BeTrue(), _ => Assert.Fail("Union item should not have matched.")); + response.Docs.ElementAt(1).Match(r => r.Found.Should().BeTrue(), _ => Assert.Fail("Union item should not have matched.")); + response.Docs.ElementAt(2).Match(r => r.Found.Should().BeFalse(), _ => Assert.Fail("Union item should not have matched.")); + } +} + +internal class Foo +{ + public string Id { get; set; } + public string Name { get; set; } +}