22using System . Collections . Generic ;
33using System . IO ;
44using System . Linq ;
5+ using System . Reflection ;
56using System . Threading . Tasks ;
67using Elasticsearch . Net ;
78using Elasticsearch . Net . Connection ;
@@ -125,6 +126,21 @@ Func<D, D> selector
125126 return this . DispatchAsync < D , Q , R , I > ( descriptor , dispatch ) ;
126127 }
127128
129+ private static readonly Lazy < MethodInfo > preserveStackTraceMethodInfo = new Lazy < MethodInfo > ( ( ) =>
130+ typeof ( Exception ) . GetMethod ( "InternalPreserveStackTrace" , BindingFlags . Instance | BindingFlags . NonPublic )
131+ ) ;
132+
133+ private static void RethrowKeepingStackTrace ( Exception exception )
134+ {
135+ // In .Net 4.5 it would be simple : ExceptionDispatchInfo.Capture(exception).Throw();
136+ // But as NEST target .Net 4.0 the old internal method must be used
137+ if ( preserveStackTraceMethodInfo . Value != null )
138+ {
139+ preserveStackTraceMethodInfo . Value . Invoke ( exception , null ) ;
140+ }
141+ throw exception ;
142+ }
143+
128144 private Task < I > DispatchAsync < D , Q , R , I > (
129145 D descriptor
130146 , Func < ElasticsearchPathInfo < Q > , D , Task < ElasticsearchResponse < R > > > dispatch
@@ -142,12 +158,13 @@ D descriptor
142158 {
143159 var mr = r . Exception . InnerException as MaxRetryException ;
144160 if ( mr != null )
145- throw mr ;
161+ RethrowKeepingStackTrace ( mr ) ;
146162
147163 var ae = r . Exception . Flatten ( ) ;
148164 if ( ae . InnerException != null )
149- throw ae . InnerException ;
150- throw ae ;
165+ RethrowKeepingStackTrace ( ae . InnerException ) ;
166+
167+ RethrowKeepingStackTrace ( ae ) ;
151168 }
152169 return ResultsSelector < D , Q , R > ( r . Result , descriptor ) ;
153170 } ) ;
0 commit comments