From 2a147c462672ca2b67c5a82d46bb1fbfe6a7eea5 Mon Sep 17 00:00:00 2001 From: Mpdreamz Date: Tue, 1 Mar 2016 21:45:38 +0100 Subject: [PATCH] improved dispatch exception to indicate which values are missing --- .../Views/_LowLevelDispatch.Generated.cshtml | 11 ---- .../LowLevelDispatch/LowLevelDispatch.cs | 54 +++++++++++++++++-- .../_Generated/_LowLevelDispatch.generated.cs | 12 ----- .../Exceptions/ExceptionTests.cs | 12 +++++ 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/CodeGeneration/CodeGeneration.LowLevelClient/Views/_LowLevelDispatch.Generated.cshtml b/src/CodeGeneration/CodeGeneration.LowLevelClient/Views/_LowLevelDispatch.Generated.cshtml index 38dc9f09591..55c71376d70 100644 --- a/src/CodeGeneration/CodeGeneration.LowLevelClient/Views/_LowLevelDispatch.Generated.cshtml +++ b/src/CodeGeneration/CodeGeneration.LowLevelClient/Views/_LowLevelDispatch.Generated.cshtml @@ -18,17 +18,6 @@ namespace Nest ///This dispatches highlevel requests into the proper lowlevel client overload method internal partial class LowLevelDispatch { - internal static ElasticsearchClientException InvalidDispatch(string apiCall, IRequest provided, HttpMethod[] methods, params string[] endpoints) - { - var sb = new StringBuilder(); - sb.AppendLine($"Dispatching {apiCall}() from NEST into to Elasticsearch.NET failed"); - sb.AppendLine($"Received a request marked as {provided.HttpMethod.GetStringValue()}"); - sb.AppendLine($"This endpoint accepts {string.Join(",", methods.Select(p=>p.GetStringValue()))}"); - sb.AppendLine($"The request might not have enough information provided to make any of these endpoints:"); - foreach (var endpoint in endpoints) - sb.AppendLine($" - {endpoint}"); - return new ElasticsearchClientException(sb.ToString()); - } @foreach (var kv in model.Endpoints) { diff --git a/src/Nest/CommonAbstractions/LowLevelDispatch/LowLevelDispatch.cs b/src/Nest/CommonAbstractions/LowLevelDispatch/LowLevelDispatch.cs index 564d1399ddf..141409a14a8 100644 --- a/src/Nest/CommonAbstractions/LowLevelDispatch/LowLevelDispatch.cs +++ b/src/Nest/CommonAbstractions/LowLevelDispatch/LowLevelDispatch.cs @@ -1,4 +1,7 @@ -using System.Linq; +using System; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; using Elasticsearch.Net; namespace Nest @@ -12,8 +15,53 @@ public LowLevelDispatch(IElasticLowLevelClient rawElasticClient) this._lowLevel = rawElasticClient; } - internal bool AllSet(params string[] pathVariables) => pathVariables.All(p => !p.IsNullOrEmpty()) && !pathVariables.All(p=>p=="_all"); + internal bool AllSet(params string[] pathVariables) => pathVariables.All(p => !p.IsNullOrEmpty()) && !pathVariables.All(p => p == "_all"); + + internal bool AllSet(params IUrlParameter[] pathVariables) => pathVariables.All(p => p != null); + + internal static Exception InvalidDispatch(string apiCall, IRequest provided, HttpMethod[] methods, params string[] endpoints) + { + var sb = new StringBuilder(); + sb.AppendLine($"Dispatching {apiCall}() from NEST into to Elasticsearch.NET failed"); + sb.AppendLine($"Received a request marked as {provided.HttpMethod.GetStringValue()}"); + sb.AppendLine($"This endpoint accepts {string.Join(",", methods.Select(p=>p.GetStringValue()))}"); + sb.AppendLine($"The request might not have enough information provided to make any of these endpoints:"); + foreach (var endpoint in endpoints) + sb.AppendLine($" - {PrettyPrintEndpoint(provided, endpoint)}"); + + return new ArgumentException(sb.ToString()); + } + + private static Regex ReplaceParams = new Regex(@"\{(.+?)\}"); + + internal static string PrettyPrintEndpoint(IRequest request, string endpoint) + { + var pretty = ReplaceParams.Replace(endpoint, (m) => + { + var key = m.Groups[1].Value.ToLowerInvariant(); + switch(key) + { + case "index" : return PrettyParam(key, request.RouteValues.Index); + case "name" : return PrettyParam(key, request.RouteValues.Name); + case "feature" : return PrettyParam(key, request.RouteValues.Feature); + case "field" : return PrettyParam(key, request.RouteValues.Field); + case "fields" : return PrettyParam(key, request.RouteValues.Fields); + case "id" : return PrettyParam(key, request.RouteValues.Id); + case "index_metric" : return PrettyParam(key, request.RouteValues.IndexMetric); + case "lang" : return PrettyParam(key, request.RouteValues.Lang); + case "metric" : return PrettyParam(key, request.RouteValues.Metric); + case "node_id" : return PrettyParam(key, request.RouteValues.NodeId); + case "repository" : return PrettyParam(key, request.RouteValues.Repository); + case "scroll_id" : return PrettyParam(key, request.RouteValues.ScrollId); + case "snapshot" : return PrettyParam(key, request.RouteValues.Snapshot); + case "type" : return PrettyParam(key, request.RouteValues.Type); + default: return PrettyParam(key, ""); + } + }); + return pretty; + } + + private static string PrettyParam(string key, string value) => $"{{{key}={(value.IsNullOrEmpty() ? "" : value)}}}"; - internal bool AllSet(params IUrlParameter[] pathVariables) => pathVariables.All(p => p != null); } } diff --git a/src/Nest/_Generated/_LowLevelDispatch.generated.cs b/src/Nest/_Generated/_LowLevelDispatch.generated.cs index aefe687674c..f45d636d173 100644 --- a/src/Nest/_Generated/_LowLevelDispatch.generated.cs +++ b/src/Nest/_Generated/_LowLevelDispatch.generated.cs @@ -15,18 +15,6 @@ namespace Nest ///This dispatches highlevel requests into the proper lowlevel client overload method internal partial class LowLevelDispatch { - internal static ElasticsearchClientException InvalidDispatch(string apiCall, IRequest provided, HttpMethod[] methods, params string[] endpoints) - { - var sb = new StringBuilder(); - sb.AppendLine($"Dispatching {apiCall}() from NEST into to Elasticsearch.NET failed"); - sb.AppendLine($"Received a request marked as {provided.HttpMethod.GetStringValue()}"); - sb.AppendLine($"This endpoint accepts {string.Join(",", methods.Select(p=>p.GetStringValue()))}"); - sb.AppendLine($"The request might not have enough information provided to make any of these endpoints:"); - foreach (var endpoint in endpoints) - sb.AppendLine($" - {endpoint}"); - return new ElasticsearchClientException(sb.ToString()); - } - internal ElasticsearchResponse BulkDispatch(IRequest p , PostData body) where T : class { switch(p.HttpMethod) diff --git a/src/Tests/ClientConcepts/Exceptions/ExceptionTests.cs b/src/Tests/ClientConcepts/Exceptions/ExceptionTests.cs index 5462ab64881..5f1decfa73a 100644 --- a/src/Tests/ClientConcepts/Exceptions/ExceptionTests.cs +++ b/src/Tests/ClientConcepts/Exceptions/ExceptionTests.cs @@ -83,5 +83,17 @@ public void ClientTestWhenThrowExceptionsDisabled() #endif response.CallDetails.ServerError.Should().BeNull(); } + + [U] + public void DispatchIndicatesMissingRouteValues() + { + var settings = new ConnectionSettings(new Uri("http://doesntexist:9200")); + var client = new ElasticClient(settings); + + Action dispatch = () => client.Index(new Project()); + var ce = dispatch.ShouldThrow(); + ce.Should().NotBeNull(); + ce.Which.Message.Should().Contain("index="); + } } }