Skip to content

Commit a7ba8cc

Browse files
russcamgmarz
authored andcommitted
Correctly handle 400 status code response (#2310)
When a ReindexOnServerResponse comes back as 400 status code, deserialize the response so that Failures is populated with more details for why things failed. Use the -1 special case in AllowedStatusCodes in the dispatch call, similar to UpdateByQuery and DeleteByQuery; IsValid will still be false as it checks Failures which will be deserialized and not be empty. Success on ApiCallDetails will be true however. Closes #2309
1 parent 8df5839 commit a7ba8cc

File tree

7 files changed

+89
-7
lines changed

7 files changed

+89
-7
lines changed

src/Elasticsearch.Net/Responses/ElasticsearchResponse.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public class ElasticsearchResponse<T> : IApiCallDetails
6868
public List<Audit> AuditTrail { get; internal set; }
6969

7070
/// <summary>
71-
/// The response is succesful or has a response code between 400-599 the call should not be retried.
72-
/// Only on 502 and 503 will this return false;
71+
/// The response is successful or has a response code between 400-599, the call should not be retried.
72+
/// Only on 502,503 and 504 will this return false;
7373
/// </summary>
7474
public bool SuccessOrKnownError =>
7575
this.Success || (HttpStatusCode >= 400 && HttpStatusCode < 599

src/Nest/CommonOptions/Failures/ShardFailure.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class ShardFailureReason : IFailureReason
4141
public class CausedBy : IFailureReason
4242
{
4343
public string Type { get; internal set; }
44+
4445
public string Reason { get; internal set; }
4546

4647
[JsonProperty("caused_by")]

src/Nest/Document/Multiple/BulkIndexByScrollFailure.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ public class BulkIndexFailureCause : IFailureReason
4141

4242
[JsonProperty("index")]
4343
public string Index { get; internal set; }
44+
45+
[JsonProperty("caused_by")]
46+
public CausedBy CausedBy { get; internal set; }
4447
}
4548
}

src/Nest/Document/Multiple/ReindexOnServer/ElasticClient-ReindexOnServer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public IReindexOnServerResponse ReindexOnServer(Func<ReindexOnServerDescriptor,
3131
/// <inheritdoc/>
3232
public IReindexOnServerResponse ReindexOnServer(IReindexOnServerRequest request) =>
3333
this.Dispatcher.Dispatch<IReindexOnServerRequest, ReindexOnServerRequestParameters, ReindexOnServerResponse>(
34-
request,
34+
this.ForceConfiguration<IReindexOnServerRequest, ReindexOnServerRequestParameters>(request, c => c.AllowedStatusCodes = new[] { -1 }),
3535
this.LowLevelDispatch.ReindexDispatch<ReindexOnServerResponse>
3636
);
3737

@@ -42,7 +42,7 @@ public IReindexOnServerResponse ReindexOnServer(IReindexOnServerRequest request)
4242
/// <inheritdoc/>
4343
public Task<IReindexOnServerResponse> ReindexOnServerAsync(IReindexOnServerRequest request, CancellationToken cancellationToken = default(CancellationToken)) =>
4444
this.Dispatcher.DispatchAsync<IReindexOnServerRequest, ReindexOnServerRequestParameters, ReindexOnServerResponse, IReindexOnServerResponse>(
45-
request,
45+
this.ForceConfiguration<IReindexOnServerRequest, ReindexOnServerRequestParameters>(request, c => c.AllowedStatusCodes = new[] { -1 }),
4646
cancellationToken,
4747
this.LowLevelDispatch.ReindexDispatchAsync<ReindexOnServerResponse>
4848
);

src/Nest/Document/Multiple/ReindexOnServer/ReindexOnServerResponse.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ public interface IReindexOnServerResponse : IResponse
5050
[JsonObject(MemberSerialization.OptIn)]
5151
public class ReindexOnServerResponse : ResponseBase, IReindexOnServerResponse
5252
{
53-
54-
public override bool IsValid => !this.Failures.HasAny();
53+
public override bool IsValid => base.IsValid && !this.Failures.HasAny();
5554

5655
public Time Took { get; internal set; }
5756

5857
/// <summary>
59-
/// Only has a value if WaitForCompletion is set to false on the request
58+
/// Only has a value if WaitForCompletion is set to <c>false</c> on the request
6059
/// </summary>
6160
public TaskId Task { get; internal set; }
6261

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Text;
3+
using Elasticsearch.Net;
4+
using FluentAssertions;
5+
using Nest;
6+
using Tests.Framework;
7+
using Tests.Framework.Integration;
8+
using Xunit;
9+
10+
namespace Tests.Reproduce
11+
{
12+
public class GithubIssue2309 : IClusterFixture<ReadOnlyCluster>
13+
{
14+
private readonly ReadOnlyCluster _cluster;
15+
16+
public GithubIssue2309(ReadOnlyCluster cluster)
17+
{
18+
_cluster = cluster;
19+
}
20+
21+
[U]
22+
public void FailedReIndexResponseMarkedAsInvalidAndContainFailures()
23+
{
24+
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
25+
26+
var json = @"{
27+
""took"": 4,
28+
""timed_out"": false,
29+
""total"": 1,
30+
""updated"": 0,
31+
""created"": 0,
32+
""deleted"": 0,
33+
""batches"": 1,
34+
""version_conflicts"": 0,
35+
""noops"": 0,
36+
""retries"": {
37+
""bulk"": 0,
38+
""search"": 0
39+
},
40+
""throttled_millis"": 0,
41+
""requests_per_second"": -1.0,
42+
""throttled_until_millis"": 0,
43+
""failures"": [{
44+
""index"": ""employees-v2"",
45+
""type"": ""employee"",
46+
""id"": ""57f7ce8df8a10336a0cf935b"",
47+
""cause"": {
48+
""type"": ""mapper_parsing_exception"",
49+
""reason"": ""failed to parse [id]"",
50+
""caused_by"": {
51+
""type"": ""number_format_exception"",
52+
""reason"": ""For input string: \""57f7ce8df8a10336a0cf935b\""""
53+
}
54+
},
55+
""status"": 400
56+
}]
57+
}";
58+
59+
var connection = new InMemoryConnection(Encoding.UTF8.GetBytes(json), 400);
60+
var settings = new ConnectionSettings(pool, connection);
61+
var client = new ElasticClient(settings);
62+
63+
var reindexResponse = client.ReindexOnServer(r => r
64+
.Source(s => s
65+
.Index("employees-v1")
66+
.Type("employee")
67+
)
68+
.Destination(d => d
69+
.Index("employees-v2")
70+
)
71+
.Conflicts(Conflicts.Proceed)
72+
);
73+
74+
reindexResponse.IsValid.Should().BeFalse();
75+
reindexResponse.Failures.Should().NotBeNull().And.HaveCount(1);
76+
}
77+
}
78+
}

src/Tests/Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@
615615
<Compile Include="QueryDsl\NotConditionlessWhen.cs" />
616616
<Compile Include="QueryDsl\Specialized\Percolate\PercolateQueryUsageTests.cs" />
617617
<Compile Include="Reproduce\GithubIssue2152.cs" />
618+
<Compile Include="Reproduce\GithubIssue2309.cs" />
618619
<Compile Include="Search\MultiSearch\MultiSearchApiTests.cs" />
619620
<Compile Include="Search\MultiSearch\MultiSearchInvalidApiTests.cs" />
620621
<Compile Include="Framework\Extensions\UriExtensions.cs" />

0 commit comments

Comments
 (0)