DefaultErrorInfoConverter.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Abp.Collections.Extensions;
  6. using Abp.Domain.Entities;
  7. using Abp.Extensions;
  8. using Abp.Localization;
  9. using Abp.Runtime.Validation;
  10. using Abp.UI;
  11. using Abp.Web.Configuration;
  12. namespace Abp.Web.Models
  13. {
  14. //TODO@Halil: I did not like constructing ErrorInfo this way. It works wlll but I think we should change it later...
  15. internal class DefaultErrorInfoConverter : IExceptionToErrorInfoConverter
  16. {
  17. private readonly IAbpWebCommonModuleConfiguration _configuration;
  18. private readonly ILocalizationManager _localizationManager;
  19. public IExceptionToErrorInfoConverter Next { set; private get; }
  20. private bool SendAllExceptionsToClients
  21. {
  22. get
  23. {
  24. return _configuration.SendAllExceptionsToClients;
  25. }
  26. }
  27. public DefaultErrorInfoConverter(
  28. IAbpWebCommonModuleConfiguration configuration,
  29. ILocalizationManager localizationManager)
  30. {
  31. _configuration = configuration;
  32. _localizationManager = localizationManager;
  33. }
  34. public ErrorInfo Convert(Exception exception)
  35. {
  36. var errorInfo = CreateErrorInfoWithoutCode(exception);
  37. if (exception is IHasErrorCode)
  38. {
  39. errorInfo.Code = (exception as IHasErrorCode).Code;
  40. }
  41. return errorInfo;
  42. }
  43. private ErrorInfo CreateErrorInfoWithoutCode(Exception exception)
  44. {
  45. if (SendAllExceptionsToClients)
  46. {
  47. return CreateDetailedErrorInfoFromException(exception);
  48. }
  49. if (exception is AggregateException && exception.InnerException != null)
  50. {
  51. var aggException = exception as AggregateException;
  52. if (aggException.InnerException is UserFriendlyException ||
  53. aggException.InnerException is AbpValidationException)
  54. {
  55. exception = aggException.InnerException;
  56. }
  57. }
  58. if (exception is UserFriendlyException)
  59. {
  60. var userFriendlyException = exception as UserFriendlyException;
  61. return new ErrorInfo(userFriendlyException.Message, userFriendlyException.Details);
  62. }
  63. if (exception is AbpValidationException)
  64. {
  65. return new ErrorInfo(L("ValidationError"))
  66. {
  67. ValidationErrors = GetValidationErrorInfos(exception as AbpValidationException),
  68. Details = GetValidationErrorNarrative(exception as AbpValidationException)
  69. };
  70. }
  71. if (exception is EntityNotFoundException)
  72. {
  73. var entityNotFoundException = exception as EntityNotFoundException;
  74. if (entityNotFoundException.EntityType != null)
  75. {
  76. return new ErrorInfo(
  77. string.Format(
  78. L("EntityNotFound"),
  79. entityNotFoundException.EntityType.Name,
  80. entityNotFoundException.Id
  81. )
  82. );
  83. }
  84. return new ErrorInfo(
  85. entityNotFoundException.Message
  86. );
  87. }
  88. if (exception is Abp.Authorization.AbpAuthorizationException)
  89. {
  90. var authorizationException = exception as Abp.Authorization.AbpAuthorizationException;
  91. return new ErrorInfo(authorizationException.Message);
  92. }
  93. return new ErrorInfo(L("InternalServerError"));
  94. }
  95. private ErrorInfo CreateDetailedErrorInfoFromException(Exception exception)
  96. {
  97. var detailBuilder = new StringBuilder();
  98. AddExceptionToDetails(exception, detailBuilder);
  99. var errorInfo = new ErrorInfo(exception.Message, detailBuilder.ToString());
  100. if (exception is AbpValidationException)
  101. {
  102. errorInfo.ValidationErrors = GetValidationErrorInfos(exception as AbpValidationException);
  103. }
  104. return errorInfo;
  105. }
  106. private void AddExceptionToDetails(Exception exception, StringBuilder detailBuilder)
  107. {
  108. //Exception Message
  109. detailBuilder.AppendLine(exception.GetType().Name + ": " + exception.Message);
  110. //Additional info for UserFriendlyException
  111. if (exception is UserFriendlyException)
  112. {
  113. var userFriendlyException = exception as UserFriendlyException;
  114. if (!string.IsNullOrEmpty(userFriendlyException.Details))
  115. {
  116. detailBuilder.AppendLine(userFriendlyException.Details);
  117. }
  118. }
  119. //Additional info for AbpValidationException
  120. if (exception is AbpValidationException)
  121. {
  122. var validationException = exception as AbpValidationException;
  123. if (validationException.ValidationErrors.Count > 0)
  124. {
  125. detailBuilder.AppendLine(GetValidationErrorNarrative(validationException));
  126. }
  127. }
  128. //Exception StackTrace
  129. if (!string.IsNullOrEmpty(exception.StackTrace))
  130. {
  131. detailBuilder.AppendLine("STACK TRACE: " + exception.StackTrace);
  132. }
  133. //Inner exception
  134. if (exception.InnerException != null)
  135. {
  136. AddExceptionToDetails(exception.InnerException, detailBuilder);
  137. }
  138. //Inner exceptions for AggregateException
  139. if (exception is AggregateException)
  140. {
  141. var aggException = exception as AggregateException;
  142. if (aggException.InnerExceptions.IsNullOrEmpty())
  143. {
  144. return;
  145. }
  146. foreach (var innerException in aggException.InnerExceptions)
  147. {
  148. AddExceptionToDetails(innerException, detailBuilder);
  149. }
  150. }
  151. }
  152. private ValidationErrorInfo[] GetValidationErrorInfos(AbpValidationException validationException)
  153. {
  154. var validationErrorInfos = new List<ValidationErrorInfo>();
  155. foreach (var validationResult in validationException.ValidationErrors)
  156. {
  157. var validationError = new ValidationErrorInfo(validationResult.ErrorMessage);
  158. if (validationResult.MemberNames != null && validationResult.MemberNames.Any())
  159. {
  160. validationError.Members = validationResult.MemberNames.Select(m => m.ToCamelCase()).ToArray();
  161. }
  162. validationErrorInfos.Add(validationError);
  163. }
  164. return validationErrorInfos.ToArray();
  165. }
  166. private string GetValidationErrorNarrative(AbpValidationException validationException)
  167. {
  168. var detailBuilder = new StringBuilder();
  169. detailBuilder.AppendLine(L("ValidationNarrativeTitle"));
  170. foreach (var validationResult in validationException.ValidationErrors)
  171. {
  172. detailBuilder.AppendFormat(" - {0}", validationResult.ErrorMessage);
  173. detailBuilder.AppendLine();
  174. }
  175. return detailBuilder.ToString();
  176. }
  177. private string L(string name)
  178. {
  179. try
  180. {
  181. return _localizationManager.GetString(AbpWebConsts.LocalizaionSourceName, name);
  182. }
  183. catch (Exception)
  184. {
  185. return name;
  186. }
  187. }
  188. }
  189. }