Skip to content

Commit 96c803c

Browse files
committed
fix #2286 normalize ApiCall and CallDetails and add better xmldocs to IResponse (#2381)
1 parent ab47816 commit 96c803c

File tree

13 files changed

+73
-36
lines changed

13 files changed

+73
-36
lines changed
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
namespace Elasticsearch.Net
22
{
3+
/// <summary>
4+
/// Implementing this interface on your response objects will cause the low level client to
5+
/// automatically set <see cref="IApiCallDetails"/> diagnostic information on the object.
6+
/// </summary>
37
public interface IBodyWithApiCallDetails
48
{
5-
IApiCallDetails CallDetails { get; set; }
9+
/// <summary>
10+
/// Sets and returns the <see cref="IApiCallDetails"/> diagnostic information
11+
/// </summary>
12+
IApiCallDetails ApiCall { get; set; }
613
}
7-
}
14+
}

src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private void Finalize(ElasticsearchResponse<TReturn> response)
125125
var passAlongConnectionStatus = response.Body as IBodyWithApiCallDetails;
126126
if (passAlongConnectionStatus != null)
127127
{
128-
passAlongConnectionStatus.CallDetails = response;
128+
passAlongConnectionStatus.ApiCall = response;
129129
}
130130
}
131131

src/Nest/CommonAbstractions/Response/ResponseBase.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,67 @@
77

88
namespace Nest
99
{
10+
/// <summary>
11+
/// Shared interface by all elasticsearch responses
12+
/// </summary>
1013
public interface IResponse : IBodyWithApiCallDetails
1114
{
15+
/// <summary>
16+
/// This property can be used to check if a response is functionally valid or not.
17+
/// This is a NEST abstraction to have a single point to check whether something wrong happend with the request.
18+
/// <para>For instance an elasticsearch bulk response always returns 200 and individual bulk items may fail, <see cref="IsValid"/> will be false in that case</para>
19+
/// <para>You can also configure the client to always throw an <see cref="ElasticsearchClientException"/> using <see cref="IConnectionConfigurationValues.ThrowExceptions"/> if the response is not valid</para>
20+
/// </summary>
1221
[JsonIgnore]
1322
bool IsValid { get; }
1423

24+
/// <summary>
25+
/// Returns the <see cref="IApiCallDetails"/> diagnostic information
26+
/// </summary>
1527
[JsonIgnore]
16-
IApiCallDetails ApiCall { get; }
28+
new IApiCallDetails ApiCall { get; }
1729

30+
/// <summary>
31+
/// If the response results in an error on elasticsearch's side an <pre>error</pre> element will be returned, this is mapped to <see cref="ServerError"/> in NEST.
32+
/// <para>This property is a shortcut to <see cref="ApiCall"/>'s <see cref="IApiCallDetails.ServerError"/> and is possibly set when <see cref="IsValid"/> is false depending on the cause of the error</para>
33+
/// <para>You can also configure the client to always throw an <see cref="ElasticsearchClientException"/> using <see cref="IConnectionConfigurationValues.ThrowExceptions"/> if the response is not valid</para>
34+
/// </summary>
1835
[JsonIgnore]
1936
ServerError ServerError { get; }
2037

38+
/// <summary>
39+
/// If the request resulted in an exception on the client side this will hold the exception that was thrown.
40+
/// <para>This property is a shortcut to <see cref="ApiCall"/>'s <see cref="IApiCallDetails.OriginalException"/> and is possibly set when <see cref="IsValid"/> is false depending on the cause of the error</para>
41+
/// <para>You can also configure the client to always throw an <see cref="ElasticsearchClientException"/> using <see cref="IConnectionConfigurationValues.ThrowExceptions"/> if the response is not valid</para>
42+
/// </summary>
2143
[JsonIgnore]
2244
Exception OriginalException { get; }
2345

46+
/// <summary>
47+
/// A lazy human readable string representation of what happened during this request for both succesful and failed requests, very useful while developing or to log when you get <see cref="IsValid"/> = false responses.
48+
/// </summary>
2449
[JsonIgnore]
2550
string DebugInformation { get; }
2651

2752
}
2853

2954
public abstract class ResponseBase : IResponse
3055
{
56+
/// <inheritdoc/>
3157
public virtual bool IsValid => (this.ApiCall?.Success ?? false) && (this.ServerError == null);
3258

33-
IApiCallDetails IBodyWithApiCallDetails.CallDetails { get; set; }
59+
IApiCallDetails IBodyWithApiCallDetails.ApiCall { get; set; }
3460

35-
public virtual IApiCallDetails ApiCall => ((IBodyWithApiCallDetails)this).CallDetails;
61+
/// <inheritdoc/>
62+
public virtual IApiCallDetails ApiCall => ((IBodyWithApiCallDetails)this).ApiCall;
3663

64+
/// <inheritdoc/>
3765
public virtual ServerError ServerError => this.ApiCall?.ServerError;
3866

67+
/// <inheritdoc/>
3968
public Exception OriginalException => this.ApiCall?.OriginalException;
4069

70+
/// <inheritdoc/>
4171
public string DebugInformation
4272
{
4373
get

src/Nest/ElasticClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private static TResponse CreateInvalidInstance<TResponse>(IApiCallDetails respon
8585
where TResponse : ResponseBase
8686
{
8787
var r = typeof(TResponse).CreateInstance<TResponse>();
88-
((IBodyWithApiCallDetails)r).CallDetails = response;
88+
((IBodyWithApiCallDetails)r).ApiCall = response;
8989
return r;
9090
}
9191

src/Nest/Search/MultiSearch/MultiSearchResponse.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ protected override void DebugIsValid(StringBuilder sb)
2424
sb.AppendLine($" search[{i.i}]: {i.item}");
2525
}
2626

27-
[JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))]
27+
[JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter))]
2828
internal IDictionary<string, object> Responses { get; set; }
2929

3030
public int TotalResponses => this.Responses.HasAny() ? this.Responses.Count() : 0;
@@ -33,7 +33,7 @@ private IEnumerable<T> _allResponses<T>() where T : class, IResponse, IBodyWithA
3333
{
3434
foreach (var r in this.Responses.Values.OfType<T>())
3535
{
36-
r.CallDetails = this.ApiCall;
36+
((IBodyWithApiCallDetails)r).ApiCall = this.ApiCall;
3737
yield return r;
3838
}
3939
}
@@ -50,7 +50,7 @@ public SearchResponse<T> GetResponse<T>(string name) where T : class
5050
this.Responses.TryGetValue(name, out response);
5151
var r = response as IBodyWithApiCallDetails;
5252
if (r != null)
53-
r.CallDetails = this.ApiCall;
53+
r.ApiCall = this.ApiCall;
5454
return response as SearchResponse<T>;
5555
}
5656
}

src/Nest/Search/Percolator/MultiPercolate/MultiPercolateResponse.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ private IEnumerable<PercolateResponse> _allResponses()
3737
foreach (var r in this.AllResponses)
3838
{
3939
IBodyWithApiCallDetails d = r;
40-
d.CallDetails = this.ApiCall;
40+
d.ApiCall = this.ApiCall;
4141
yield return r;
4242
}
4343
}

src/Profiling/Async/IndexAsyncOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public override async Task ProfileAsync(IElasticClient client, ColoredConsoleWri
2121
await client.IndexAsync(Developer.Generator.Generate(), d => d.Index<Developer>()).ConfigureAwait(false);
2222

2323
if (!indexResponse.IsValid)
24-
output.WriteOrange($"error with id {indexResponse.Id}. message: {indexResponse.CallDetails.OriginalException}");
24+
output.WriteOrange($"error with id {indexResponse.Id}. message: {indexResponse.ApiCall.OriginalException}");
2525
}
2626
}
2727
}

src/Profiling/Async/SearchAsyncOperation.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public override async Task SetupAsync(IElasticClient client, ColoredConsoleWrite
2323
var indexResponse = await client.IndexAsync(_developer, d => d.Index<Developer>().Refresh(Refresh.True)).ConfigureAwait(false);
2424

2525
if (!indexResponse.IsValid)
26-
output.WriteOrange($"error with id {indexResponse.Id}. message: {indexResponse.CallDetails.OriginalException}");
26+
output.WriteOrange($"error with id {indexResponse.Id}. message: {indexResponse.ApiCall.OriginalException}");
2727
}
2828

2929
public override async Task ProfileAsync(IElasticClient client, ColoredConsoleWriter output)
@@ -46,7 +46,7 @@ public override async Task ProfileAsync(IElasticClient client, ColoredConsoleWri
4646

4747
if (!searchResponse.IsValid)
4848
output.WriteOrange(
49-
$"error searching for {nameof(Developer)}. message: {searchResponse.CallDetails.OriginalException}");
49+
$"error searching for {nameof(Developer)}. message: {searchResponse.ApiCall.OriginalException}");
5050

5151
if (!searchResponse.Documents.Any())
5252
output.WriteOrange($"did not find matching {nameof(Developer)} for search.");
@@ -58,7 +58,7 @@ public override async Task TeardownAsync(IElasticClient client, ColoredConsoleWr
5858
var deleteResponse = await client.DeleteAsync<Developer>(_developer, d => d.Index<Developer>()).ConfigureAwait(false);
5959

6060
if (!deleteResponse.IsValid)
61-
output.WriteOrange($"error with id {deleteResponse.Id}. message: {deleteResponse.CallDetails.OriginalException}");
61+
output.WriteOrange($"error with id {deleteResponse.Id}. message: {deleteResponse.ApiCall.OriginalException}");
6262
}
6363
}
6464
}

src/Tests/ClientConcepts/Exceptions/ExceptionTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ public void ServerTestWhenThrowExceptionsDisabled()
6262
// HttpClient does not throw on "known error" status codes (i.e. 404) thus OriginalException should not be set
6363
response.CallDetails.OriginalException.Should().BeNull();
6464
#else
65-
response.CallDetails.OriginalException.Should().NotBeNull();
65+
response.ApiCall.OriginalException.Should().NotBeNull();
6666
#endif
67-
response.CallDetails.ServerError.Should().NotBeNull();
68-
response.CallDetails.ServerError.Status.Should().BeGreaterThan(0);
67+
response.ApiCall.ServerError.Should().NotBeNull();
68+
response.ApiCall.ServerError.Status.Should().BeGreaterThan(0);
6969
}
7070

7171
//[I]
@@ -78,9 +78,9 @@ public void ClientTestWhenThrowExceptionsDisabled()
7878
// HttpClient does not throw on "known error" status codes (i.e. 404) thus OriginalException should not be set
7979
response.CallDetails.OriginalException.Should().BeNull();
8080
#else
81-
response.CallDetails.OriginalException.Should().NotBeNull();
81+
response.ApiCall.OriginalException.Should().NotBeNull();
8282
#endif
83-
response.CallDetails.ServerError.Should().BeNull();
83+
response.ApiCall.ServerError.Should().BeNull();
8484
}
8585

8686
//TODO figure out a way to trigger this again

src/Tests/Framework/EndpointTests/ApiIntegrationTestBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ protected override Task AssertOnAllResponses(Action<TResponse> assert)
4444

4545
return base.AssertOnAllResponses((r) =>
4646
{
47-
if (TestClient.Configuration.RunIntegrationTests && !r.IsValid && r.CallDetails.OriginalException != null
48-
&& IsNotRequestExceptionType(r.CallDetails.OriginalException.GetType()))
47+
if (TestClient.Configuration.RunIntegrationTests && !r.IsValid && r.ApiCall.OriginalException != null
48+
&& IsNotRequestExceptionType(r.ApiCall.OriginalException.GetType()))
4949
{
50-
ExceptionDispatchInfo.Capture(r.CallDetails.OriginalException).Throw();
50+
ExceptionDispatchInfo.Capture(r.ApiCall.OriginalException).Throw();
5151
return;
5252
}
5353

0 commit comments

Comments
 (0)