/// <summary> /// Sets the properties from an exception. /// </summary> /// <param name="exception">The exception to populate properties from.</param> /// <param name="log">The log implementation used for diagnostic information.</param> public static Error ToErrorModel(this Exception exception #if EMBEDDED , IExceptionlessLog log = null #endif ) { if (exception == null) { throw new ArgumentNullException("exception"); } #if EMBEDDED if (log == null) { log = new NullExceptionlessLog(); } #endif Type type = exception.GetType(); var error = new Error { Message = exception.GetMessage(), #if EMBEDDED Modules = GetLoadedModules(log), #else Modules = GetLoadedModules(), #endif Type = type.FullName }; error.PopulateStackTrace(error, exception); #if !SILVERLIGHT try { PropertyInfo info = type.GetProperty("HResult", BindingFlags.NonPublic | BindingFlags.Instance); if (info != null) { error.Code = info.GetValue(exception, null).ToString(); } } catch (Exception) {} #endif if (exception.TargetSite != null) { error.TargetMethod = new Method(); error.TargetMethod.PopulateMethod(error, exception.TargetSite); } // TODO: Test adding non-serializable objects to ExtendedData and see what happens try { Dictionary <string, object> extraProperties = type.GetPublicProperties().Where(p => !_exceptionExclusions.Contains(p.Name)).ToDictionary(p => p.Name, p => { try { return(p.GetValue(exception, null)); } catch {} return(null); }); extraProperties = extraProperties.Where(kvp => !ValueIsEmpty(kvp.Value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (extraProperties.Count > 0 && !error.ExtendedData.ContainsKey(ExtendedDataDictionary.EXCEPTION_INFO_KEY)) { error.AddObject(new ExtendedDataInfo { Data = extraProperties, Name = ExtendedDataDictionary.EXCEPTION_INFO_KEY, IgnoreSerializationErrors = true, MaxDepthToSerialize = 5 }); } } catch {} if (exception.InnerException != null) { error.Inner = exception.InnerException.ToErrorModel(); } return(error); }