11using System ;
22using System . Collections . Generic ;
3+ using System . Globalization ;
34using System . IO ;
5+ using System . Linq ;
46using System . Reflection ;
57using System . Runtime . Serialization ;
68using System . Text ;
@@ -12,75 +14,149 @@ namespace Tests.Reproduce
1214{
1315 public class GithubIssue2052
1416 {
17+ private const string _objectMessage = "My message" ;
18+ private static object _bulkHeader =
19+ new { index = new { _index = "myIndex" , _type = "myDocumentType" } } ;
20+ private readonly ElasticLowLevelClient _client ;
21+ private AssemblyName _assemblyName = new AssemblyName ( typeof ( GithubIssue2052 ) . Assembly . FullName ) ;
1522
16- [ U ]
17- public void BadSimpleJsonDeserialization ( )
23+ public GithubIssue2052 ( )
1824 {
1925
20- var ex = this . GimmeACaughtException ( ) ;
21-
22- var document = new Dictionary < string , object > {
23- { "message" , "My message" } ,
24- { "exception" , ex }
25- } ;
26-
2726 var pool = new StaticConnectionPool ( new List < Uri > { new Uri ( "http://localhost:9200" ) } ) ;
2827 var memoryConnection = new InMemoryConnection ( ) ;
2928 var connectionSettings = new ConnectionConfiguration ( pool , memoryConnection )
3029 . DisableDirectStreaming ( ) ;
31- var client = new ElasticLowLevelClient ( connectionSettings ) ;
30+ this . _client = new ElasticLowLevelClient ( connectionSettings ) ;
31+ }
3232
3333
34- var header = new { index = new { _index = "myIndex" , _type = "myDocumentType" } } ;
35- var payload = new List < object > {
36- header ,
37- document
38- } ;
39- var response = client . Bulk < byte [ ] > ( payload ) ;
34+ [ U ] public void SingleThrownExceptionCanBeSerializedUsingSimpleJson ( )
35+ {
36+
37+ var ex = this . GimmeACaughtException ( ) ;
4038
39+ var request = this . CreateRequest ( ex ) ;
40+ var postData = this . CreatePostData ( ex ) ;
4141
42- var request = Encoding . UTF8 . GetString ( response . RequestBodyInBytes ) ;
43- var a = new AssemblyName ( this . GetType ( ) . Assembly . FullName ) ;
42+ this . AssertRequestEquals ( request , postData ) ;
43+ }
44+
45+ [ U ] public void MultipleThrownExceptionCanBeSerializedUsingSimpleJson ( )
46+ {
47+
48+ var ex = this . GimmeAnExceptionWithInnerException ( ) ;
49+
50+ var request = this . CreateRequest ( ex ) ;
51+ var postData = this . CreatePostData ( ex ) ;
52+
53+ this . AssertRequestEquals ( request , postData ) ;
54+ }
4455
45- var si = new SerializationInfo ( ex . GetType ( ) , new FormatterConverter ( ) ) ;
46- var sc = new StreamingContext ( ) ;
47- ex . GetObjectData ( si , sc ) ;
56+ private PostData < object > CreatePostData ( Exception e )
57+ {
4858 PostData < object > postData = new List < object >
4959 {
50- header ,
60+ _bulkHeader ,
5161 new
5262 {
5363 message = "My message" ,
54- exception = new
55- {
56- ClassName = "System.Exception" ,
57- Message = "Some exception" ,
58- Source = "Tests" ,
59- StackTraceString = ex . StackTrace ,
60- RemoteStackTraceString = si . GetString ( "RemoteStackTraceString" ) ,
61- RemoteStackIndex = 0 ,
62- HResult = si . GetInt32 ( "HResult" ) ,
63- HelpURL = si . GetString ( "HelpURL" ) ,
64- ExceptionMethod = new
65- {
66- Name = nameof ( GimmeACaughtException ) ,
67- AssemblyName = a . Name ,
68- AssemblyVersion = a . Version . ToString ( ) ,
69- AssemblyCulture = a . CultureName ,
70- ClassName = this . GetType ( ) . FullName ,
71- Signature = $ "System.Exception { nameof ( GimmeACaughtException ) } ()",
72- MemberType = 8
73- }
74- } ,
64+ exception = this . ExceptionJson ( e ) . ToArray ( ) ,
7565 }
7666 } ;
67+ return postData ;
68+ }
69+
70+ private IEnumerable < object > ExceptionJson ( Exception e )
71+ {
72+ int depth = 0 ;
73+ int maxExceptions = 20 ;
74+ do
75+ {
76+
77+ var si = new SerializationInfo ( e . GetType ( ) , new FormatterConverter ( ) ) ;
78+ var sc = new StreamingContext ( ) ;
79+ e . GetObjectData ( si , sc ) ;
80+
81+ var helpUrl = si . GetString ( "HelpURL" ) ;
82+ var stackTrace = si . GetString ( "StackTraceString" ) ;
83+ var remoteStackTrace = si . GetString ( "RemoteStackTraceString" ) ;
84+ var remoteStackIndex = si . GetInt32 ( "RemoteStackIndex" ) ;
85+ var exceptionMethod = si . GetString ( "ExceptionMethod" ) ;
86+ var hresult = si . GetInt32 ( "HResult" ) ;
87+ var source = si . GetString ( "Source" ) ;
88+ var className = si . GetString ( "ClassName" ) ;
7789
90+ yield return new
91+ {
92+ Depth = depth ,
93+ ClassName = className ,
94+ Message = e . Message ,
95+ Source = source ,
96+ StackTraceString = stackTrace ,
97+ RemoteStackTraceString = remoteStackTrace ,
98+ RemoteStackIndex = remoteStackIndex ,
99+ HResult = hresult ,
100+ HelpURL = helpUrl ,
101+ ExceptionMethod = this . WriteStructuredExceptionMethod ( exceptionMethod )
102+ } ;
103+ depth ++ ;
104+ e = e . InnerException ;
78105
106+ }
107+ while ( depth < maxExceptions && e != null ) ;
108+ }
79109
110+ private object WriteStructuredExceptionMethod ( string exceptionMethodString )
111+ {
112+ if ( string . IsNullOrWhiteSpace ( exceptionMethodString ) ) return null ;
80113
114+ var args = exceptionMethodString . Split ( '\0 ' , '\n ' ) ;
115+
116+ if ( args . Length != 5 ) return null ;
117+
118+ var memberType = Int32 . Parse ( args [ 0 ] , CultureInfo . InvariantCulture ) ;
119+ var name = args [ 1 ] ;
120+ var assemblyName = args [ 2 ] ;
121+ var className = args [ 3 ] ;
122+ var signature = args [ 4 ] ;
123+ var an = new AssemblyName ( assemblyName ) ;
124+ return new
125+ {
126+ Name = name ,
127+ AssemblyName = an . Name ,
128+ AssemblyVersion = an . Version . ToString ( ) ,
129+ AssemblyCulture = an . CultureName ,
130+ ClassName = className ,
131+ Signature = signature ,
132+ MemberType = memberType ,
133+ } ;
134+ }
135+
136+ private string CreateRequest ( Exception ex )
137+ {
138+ var document = new Dictionary < string , object > {
139+ { "message" , _objectMessage } ,
140+ { "exception" , ex }
141+ } ;
142+
143+
144+ var payload = new List < object > {
145+ _bulkHeader ,
146+ document
147+ } ;
148+ var response = this . _client . Bulk < byte [ ] > ( payload ) ;
149+
150+
151+ var request = Encoding . UTF8 . GetString ( response . RequestBodyInBytes ) ;
152+ return request ;
153+ }
154+
155+ private void AssertRequestEquals ( string request , PostData < object > postData )
156+ {
81157 using ( var ms = new MemoryStream ( ) )
82158 {
83- postData . Write ( ms , client . Settings ) ;
159+ postData . Write ( ms , this . _client . Settings ) ;
84160 var expectedString = Encoding . UTF8 . GetString ( ms . ToArray ( ) ) ;
85161 request . Should ( ) . Be ( expectedString ) ;
86162 }
@@ -98,5 +174,18 @@ private Exception GimmeACaughtException()
98174 }
99175 }
100176
177+
178+ private Exception GimmeAnExceptionWithInnerException ( )
179+ {
180+ try
181+ {
182+ var e = this . GimmeACaughtException ( ) ;
183+ throw new Exception ( "Some exception" , e ) ;
184+ }
185+ catch ( Exception e )
186+ {
187+ return e ;
188+ }
189+ }
101190 }
102191}
0 commit comments