Skip to content

Commit 62b0db7

Browse files
committed
Fix #723 Source() should return null on 404
1 parent 8a2e21b commit 62b0db7

File tree

5 files changed

+84
-30
lines changed

5 files changed

+84
-30
lines changed

src/Elasticsearch.Net/Connection/RequestState/ITransportRequestState.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using Elasticsearch.Net.Connection.Configuration;
45

56
namespace Elasticsearch.Net.Connection.RequestState
@@ -14,5 +15,6 @@ internal interface ITransportRequestState
1415
int? Seed { get; set; }
1516
Uri CurrentNode { get; set; }
1617
List<RequestMetrics> RequestMetrics { get; set; }
18+
Func<IElasticsearchResponse, Stream, object> ResponseCreationOverride { get; set; }
1719
}
1820
}

src/Elasticsearch.Net/Connection/RequestState/TransportRequestState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public IRequestConfiguration RequestConfiguration
3737

3838
public int? Seed { get; set; }
3939

40-
public Func<IElasticsearchResponse, Stream, object> DeserializationState { get; private set; }
40+
public Func<IElasticsearchResponse, Stream, object> ResponseCreationOverride { get; set; }
4141

4242
public bool SniffedOnConnectionFailure { get; set; }
4343

@@ -88,7 +88,7 @@ public TransportRequestState(
8888
{
8989
if (this.RequestParameters.QueryString != null)
9090
this.Path += RequestParameters.QueryString.ToNameValueCollection(ClientSettings.Serializer).ToQueryString();
91-
this.DeserializationState = this.RequestParameters.DeserializationState;
91+
this.ResponseCreationOverride = this.RequestParameters.DeserializationState;
9292
}
9393
}
9494

src/Elasticsearch.Net/Connection/Transport.cs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ private ElasticsearchResponse<T> DoRequest<T>(TransportRequestState<T> requestSt
305305
{
306306
var error = ThrowOrGetErrorFromStreamResponse(requestState, streamResponse);
307307

308-
var typedResponse = this.StreamToTypedResponse<T>(streamResponse, requestState.DeserializationState);
308+
var typedResponse = this.StreamToTypedResponse<T>(streamResponse, requestState);
309309
this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, typedResponse, streamResponse);
310310
aliveResponse = typedResponse.SuccessOrKnownError;
311311
return typedResponse;
@@ -438,7 +438,7 @@ private Task<ElasticsearchResponse<T>> FinishOrRetryRequestAsync<T>(TransportReq
438438
rq.Finish(t.Result.Success, t.Result.HttpStatusCode);
439439
rq.Dispose();
440440
var error = ThrowOrGetErrorFromStreamResponse(requestState, t.Result);
441-
return this.StreamToTypedResponseAsync<T>(t.Result, requestState.DeserializationState)
441+
return this.StreamToTypedResponseAsync<T>(t.Result, requestState)
442442
.ContinueWith(tt =>
443443
{
444444

@@ -524,9 +524,7 @@ private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse<T>(
524524
TransportRequestState<T> requestState,
525525
ElasticsearchResponse<Stream> streamResponse)
526526
{
527-
if ((streamResponse.Success || requestState.RequestConfiguration != null) &&
528-
(streamResponse.Success || requestState.RequestConfiguration == null ||
529-
requestState.RequestConfiguration.AllowedStatusCodes.Any(i => i == streamResponse.HttpStatusCode)))
527+
if (IsValidResponse(requestState, streamResponse))
530528
return null;
531529

532530
ElasticsearchServerError error = null;
@@ -565,6 +563,13 @@ private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse<T>(
565563
return error;
566564
}
567565

566+
private static bool IsValidResponse(ITransportRequestState requestState, IElasticsearchResponse streamResponse)
567+
{
568+
return (streamResponse.Success || requestState.RequestConfiguration != null) &&
569+
(streamResponse.Success || requestState.RequestConfiguration == null ||
570+
requestState.RequestConfiguration.AllowedStatusCodes.Any(i => i == streamResponse.HttpStatusCode));
571+
}
572+
568573
private bool TypeOfResponseCopiesDirectly<T>()
569574
{
570575
var type = typeof(T);
@@ -573,7 +578,7 @@ private bool TypeOfResponseCopiesDirectly<T>()
573578

574579
private ElasticsearchResponse<T> StreamToTypedResponse<T>(
575580
ElasticsearchResponse<Stream> streamResponse,
576-
Func<IElasticsearchResponse, Stream, object> deserializationState
581+
ITransportRequestState requestState
577582
)
578583
{
579584
//if the user explicitly wants a stream returned the undisposed stream
@@ -589,7 +594,7 @@ Func<IElasticsearchResponse, Stream, object> deserializationState
589594

590595
var type = typeof(T);
591596
if (!(this.Settings.KeepRawResponse || this.TypeOfResponseCopiesDirectly<T>()))
592-
return this._deserializeToResponse(cs, streamResponse.Response, deserializationState);
597+
return this._deserializeToResponse(cs, streamResponse.Response, requestState);
593598

594599

595600
if (streamResponse.Response != null)
@@ -607,11 +612,14 @@ Func<IElasticsearchResponse, Stream, object> deserializationState
607612
this.SetByteResult(cs as ElasticsearchResponse<byte[]>, bytes);
608613
return cs;
609614
}
610-
return this._deserializeToResponse(cs, memoryStream, deserializationState);
615+
return this._deserializeToResponse(cs, memoryStream, requestState);
611616
}
612617
}
613618

614-
private Task<ElasticsearchResponse<T>> StreamToTypedResponseAsync<T>(ElasticsearchResponse<Stream> streamResponse, object deserializationState)
619+
private Task<ElasticsearchResponse<T>> StreamToTypedResponseAsync<T>(
620+
ElasticsearchResponse<Stream> streamResponse,
621+
ITransportRequestState requestState
622+
)
615623
{
616624
var tcs = new TaskCompletionSource<ElasticsearchResponse<T>>();
617625

@@ -633,7 +641,7 @@ private Task<ElasticsearchResponse<T>> StreamToTypedResponseAsync<T>(Elasticsear
633641
}
634642

635643
if (!(this.Settings.KeepRawResponse || this.TypeOfResponseCopiesDirectly<T>()))
636-
return _deserializeAsyncToResponse(streamResponse.Response, deserializationState, cs);
644+
return _deserializeAsyncToResponse(streamResponse.Response, requestState, cs);
637645

638646
var memoryStream = new MemoryStream();
639647
return this.Iterate(this.ReadStreamAsync(streamResponse.Response, memoryStream), memoryStream)
@@ -658,7 +666,7 @@ private Task<ElasticsearchResponse<T>> StreamToTypedResponseAsync<T>(Elasticsear
658666
return tcs.Task;
659667
}
660668

661-
return _deserializeAsyncToResponse(readStream, deserializationState, cs);
669+
return _deserializeAsyncToResponse(readStream, requestState, cs);
662670
})
663671
.Unwrap();
664672

@@ -667,14 +675,13 @@ private Task<ElasticsearchResponse<T>> StreamToTypedResponseAsync<T>(Elasticsear
667675
private ElasticsearchResponse<T> _deserializeToResponse<T>(
668676
ElasticsearchResponse<T> typedResponse,
669677
Stream responseStream,
670-
Func<IElasticsearchResponse, Stream, object> deserializationState)
678+
ITransportRequestState requestState
679+
)
671680
{
672-
if (responseStream == null
673-
|| (!typedResponse.HttpStatusCode.HasValue)
674-
|| ((typedResponse.HttpStatusCode.Value < 200 || typedResponse.HttpStatusCode >= 300) && typedResponse.HttpStatusCode != 404)
675-
)
681+
if (!IsValidResponse(requestState, typedResponse))
676682
return typedResponse;
677683

684+
var deserializationState = requestState.ResponseCreationOverride;
678685
var customConverter = deserializationState as Func<IElasticsearchResponse, Stream, T>;
679686
if (customConverter != null)
680687
{
@@ -690,33 +697,35 @@ private ElasticsearchResponse<T> _deserializeToResponse<T>(
690697
return typedResponse;
691698
}
692699

693-
private Task<ElasticsearchResponse<T>> _deserializeAsyncToResponse<T>(Stream response, object deserializationState, ElasticsearchResponse<T> cs)
700+
private Task<ElasticsearchResponse<T>> _deserializeAsyncToResponse<T>(
701+
Stream response,
702+
ITransportRequestState requestState,
703+
ElasticsearchResponse<T> typedResponse
704+
)
694705
{
695706
var tcs = new TaskCompletionSource<ElasticsearchResponse<T>>();
696-
if (response == null
697-
|| (!cs.HttpStatusCode.HasValue)
698-
|| ((cs.HttpStatusCode.Value < 200 || cs.HttpStatusCode >= 300) && cs.HttpStatusCode != 404)
699-
)
707+
if (!IsValidResponse(requestState, typedResponse))
700708
{
701-
tcs.SetResult(cs);
709+
tcs.SetResult(typedResponse);
702710
return tcs.Task;
703711
}
704-
var customConverter = deserializationState as Func<IElasticsearchResponse, Stream, T>;
712+
var responseInstantiater = requestState.ResponseCreationOverride;
713+
var customConverter = responseInstantiater as Func<IElasticsearchResponse, Stream, T>;
705714
if (customConverter != null)
706715
{
707716
using (response)
708717
{
709-
var t = customConverter(cs, response);
710-
cs.Response = t;
711-
tcs.SetResult(cs);
718+
var t = customConverter(typedResponse, response);
719+
typedResponse.Response = t;
720+
tcs.SetResult(typedResponse);
712721
return tcs.Task;
713722
}
714723
}
715724
return this.Serializer.DeserializeAsync<T>(response)
716725
.ContinueWith(t =>
717726
{
718-
cs.Response = t.Result;
719-
return cs;
727+
typedResponse.Response = t.Result;
728+
return typedResponse;
720729
});
721730
}
722731

src/Tests/Nest.Tests.Integration/Nest.Tests.Integration.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
<Compile Include="RawCalls\DynamicNullTests.cs" />
167167
<Compile Include="Mapping\NotAnalyzedTest.cs" />
168168
<Compile Include="RawCalls\ReturnTypesTest.cs" />
169+
<Compile Include="Reproduce\Reproduce723Tests.cs" />
169170
<Compile Include="Reproduce\Reproduce643Tests.cs" />
170171
<Compile Include="Reproduce\Reproduce628Tests.cs" />
171172
<Compile Include="Reproduce\Reproduce487Tests.cs" />
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Elasticsearch.Net;
5+
using Nest.Tests.MockData;
6+
using Nest.Tests.MockData.Domain;
7+
using NUnit.Framework;
8+
using System.Diagnostics;
9+
using FluentAssertions;
10+
11+
namespace Nest.Tests.Integration.Reproduce
12+
{
13+
/// <summary>
14+
/// tests to reproduce reported errors
15+
/// </summary>
16+
[TestFixture]
17+
public class Reproduce723Tests : IntegrationTests
18+
{
19+
20+
/// <summary>
21+
/// https://github.com/Mpdreamz/NEST/issues/723
22+
/// </summary>
23+
[Test]
24+
public void GetInvalidIndexShouldReturnNull()
25+
{
26+
const string indexName = "indexthatdoesnotexist";
27+
var elasticSearchProject = this._client.Source<ElasticsearchProject>(4, indexName);
28+
29+
elasticSearchProject.Should().BeNull();
30+
}
31+
32+
[Test]
33+
public void GetInvalidIndexShouldThrow_OnClientThatThrows()
34+
{
35+
const string indexName = "indexthatdoesnotexist";
36+
var e = Assert.Throws<ElasticsearchServerException>(() => this._clientThatThrows.Source<ElasticsearchProject>(4, indexName));
37+
e.ExceptionType.Should().Be("IndexMissingException");
38+
39+
}
40+
41+
}
42+
}

0 commit comments

Comments
 (0)