@@ -38,14 +38,29 @@ public class FailureDetails : IEquatable<FailureDetails>
3838 /// <param name="stackTrace">The exception stack trace.</param>
3939 /// <param name="innerFailure">The inner cause of the failure.</param>
4040 /// <param name="isNonRetriable">Whether the failure is non-retriable.</param>
41+ /// <param name="properties">Additional properties associated with the failure.</param>
4142 [ JsonConstructor ]
42- public FailureDetails ( string errorType , string errorMessage , string ? stackTrace , FailureDetails ? innerFailure , bool isNonRetriable )
43+ public FailureDetails ( string errorType , string errorMessage , string ? stackTrace , FailureDetails ? innerFailure , bool isNonRetriable , IDictionary < string , object ? > ? properties = null )
4344 {
4445 this . ErrorType = errorType ;
4546 this . ErrorMessage = errorMessage ;
4647 this . StackTrace = stackTrace ;
4748 this . InnerFailure = innerFailure ;
4849 this . IsNonRetriable = isNonRetriable ;
50+ this . Properties = properties ;
51+ }
52+
53+ /// <summary>
54+ /// Initializes a new instance of the <see cref="FailureDetails"/> class.
55+ /// </summary>
56+ /// <param name="errorType">The name of the error, which is expected to the the namespace-qualified name of the exception type.</param>
57+ /// <param name="errorMessage">The message associated with the error, which is expected to be the exception's <see cref="Exception.Message"/> property.</param>
58+ /// <param name="stackTrace">The exception stack trace.</param>
59+ /// <param name="innerFailure">The inner cause of the failure.</param>
60+ /// <param name="isNonRetriable">Whether the failure is non-retriable.</param>
61+ public FailureDetails ( string errorType , string errorMessage , string ? stackTrace , FailureDetails ? innerFailure , bool isNonRetriable )
62+ : this ( errorType , errorMessage , stackTrace , innerFailure , isNonRetriable , properties : null )
63+ {
4964 }
5065
5166 /// <summary>
@@ -54,7 +69,7 @@ public FailureDetails(string errorType, string errorMessage, string? stackTrace,
5469 /// <param name="e">The exception used to generate the failure details.</param>
5570 /// <param name="innerFailure">The inner cause of the failure.</param>
5671 public FailureDetails ( Exception e , FailureDetails innerFailure )
57- : this ( e . GetType ( ) . FullName , GetErrorMessage ( e ) , e . StackTrace , innerFailure , false )
72+ : this ( e , innerFailure , properties : null )
5873 {
5974 }
6075
@@ -63,7 +78,28 @@ public FailureDetails(Exception e, FailureDetails innerFailure)
6378 /// </summary>
6479 /// <param name="e">The exception used to generate the failure details.</param>
6580 public FailureDetails ( Exception e )
66- : this ( e . GetType ( ) . FullName , GetErrorMessage ( e ) , e . StackTrace , FromException ( e . InnerException ) , false )
81+ : this ( e , properties : null )
82+ {
83+ }
84+
85+ /// <summary>
86+ /// Initializes a new instance of the <see cref="FailureDetails"/> class from an exception object.
87+ /// </summary>
88+ /// <param name="e">The exception used to generate the failure details.</param>
89+ /// <param name="properties">The exception properties to include in failure details.</param>
90+ public FailureDetails ( Exception e , IDictionary < string , object ? > ? properties )
91+ : this ( e . GetType ( ) . FullName , GetErrorMessage ( e ) , e . StackTrace , FromException ( e . InnerException ) , false , properties )
92+ {
93+ }
94+
95+ /// <summary>
96+ /// Initializes a new instance of the <see cref="FailureDetails"/> class from an exception object.
97+ /// </summary>
98+ /// <param name="e">The exception used to generate the failure details.</param>
99+ /// <param name="innerFailure">The inner cause of the failure.</param>
100+ /// <param name="properties">The exception properties to include in failure details.</param>
101+ public FailureDetails ( Exception e , FailureDetails innerFailure , IDictionary < string , object ? > ? properties )
102+ : this ( e . GetType ( ) . FullName , GetErrorMessage ( e ) , e . StackTrace , innerFailure , false , properties )
67103 {
68104 }
69105
@@ -74,6 +110,7 @@ public FailureDetails()
74110 {
75111 this . ErrorType = "None" ;
76112 this . ErrorMessage = string . Empty ;
113+ this . Properties = null ;
77114 }
78115
79116 /// <summary>
@@ -85,6 +122,16 @@ protected FailureDetails(SerializationInfo info, StreamingContext context)
85122 this . ErrorMessage = info . GetString ( nameof ( this . ErrorMessage ) ) ;
86123 this . StackTrace = info . GetString ( nameof ( this . StackTrace ) ) ;
87124 this . InnerFailure = ( FailureDetails ) info . GetValue ( nameof ( this . InnerFailure ) , typeof ( FailureDetails ) ) ;
125+ // Handle backward compatibility for Properties property - defaults to null
126+ try
127+ {
128+ this . Properties = ( IDictionary < string , object ? > ? ) info . GetValue ( nameof ( this . Properties ) , typeof ( IDictionary < string , object ? > ) ) ;
129+ }
130+ catch ( SerializationException )
131+ {
132+ // Default to null for backward compatibility
133+ this . Properties = null ;
134+ }
88135 }
89136
90137 /// <summary>
@@ -112,6 +159,11 @@ protected FailureDetails(SerializationInfo info, StreamingContext context)
112159 /// </summary>
113160 public bool IsNonRetriable { get ; }
114161
162+ /// <summary>
163+ /// Gets additional properties associated with the failure.
164+ /// </summary>
165+ public IDictionary < string , object ? > ? Properties { get ; }
166+
115167 /// <summary>
116168 /// Gets a debug-friendly description of the failure information.
117169 /// </summary>
@@ -204,7 +256,13 @@ static string GetErrorMessage(Exception e)
204256
205257 static FailureDetails ? FromException ( Exception ? e )
206258 {
207- return e == null ? null : new FailureDetails ( e ) ;
259+ return FromException ( e , properties : null ) ;
208260 }
261+
262+ static FailureDetails ? FromException ( Exception ? e , IDictionary < string , object ? > ? properties )
263+ {
264+ return e == null ? null : new FailureDetails ( e , properties : properties ) ;
265+ }
266+
209267 }
210268}
0 commit comments