从Web API错误中筛选异常堆栈跟踪

本文关键字:异常 堆栈 跟踪 筛选 Web API 错误 | 更新日期: 2023-09-27 17:52:46

我有一个web api与我沟通。

当发生异常时,我得到以下JSON模板:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Index was outside the bounds of the array.",
  "ExceptionType": "System.IndexOutOfRangeException",
  "StackTrace": "   at WebApiTest.TestController.Post(Uri uri) in c:''Temp''WebApiTest''WebApiTest''TestController.cs:line 18'r'n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClassf.<GetExecutor>b__9(Object instance, Object[] methodParameters)'r'n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)'r'n   at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)"
}

我希望JSON包含的只是"Message"answers"ExceptionMessage"属性,但仍然可以根据需要控制返回完整的堆栈跟踪。

我试过使用

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy

但似乎这是全部或没有,要么只是单一的"Message"属性或获得完整的对象时,将其设置为"Always"。

有什么简单的方法可以做到这一点吗?

感谢您的帮助。

从Web API错误中筛选异常堆栈跟踪

在我的代码中,我使用异常过滤器来做你所要求的,查看以下两个链接了解更多细节

Web API异常处理

Web API全局错误处理

我们在代码中所做的如下:

  1. 创建例外过滤器:

    public class ViewRExceptionFilterAttribute : ExceptionFilterAttribute
    {
    // Global context message for the modifying the context response in case of exception
    private string globalHttpContextMessage;
    /// <summary>
    ///     Overriding the OnException method as part of the Filter, which would detect the type of Action and would
    ///     accordingly modify the Http
    ///     context response
    /// </summary>
    /// <param name="context"></param>
    public override void OnException(HttpActionExecutedContext context)
    {
        // Dictionary with Type and Action for various Type actions, current method is called by various types
        Dictionary<Type, Action> dictionaryExceptionTypeAction = new Dictionary<Type, Action>();
        // Add an action for a given exception type
        dictionaryExceptionTypeAction.Add(typeof (ViewRClientException), ViewRClientExceptionAction(context.Exception));            
        dictionaryExceptionTypeAction.Add(typeof (Exception), SystemExceptionAction(context.Exception));
        // Execute an Action for a given exception type
        if (context.Exception is ViewRClientException)
            dictionaryExceptionTypeAction[typeof (ViewRClientException)]();
       else
            dictionaryExceptionTypeAction[typeof (Exception)]();
        // Reset the Context Response using global string which is set in the Exception specific action
        context.Response = new HttpResponseMessage
        {
            Content = new StringContent(globalHttpContextMessage)
        };
    }
    /// <summary>
    ///     Action method for the ViewRClientException, creates the Exception Message, which is Json serialized
    /// </summary>
    /// <returns></returns>
    private Action ViewRClientExceptionAction(Exception viewRException)
    {
        return (() =>
        {
            LogException(viewRException);
            ViewRClientException currentException = viewRException as ViewRClientException;
            ExceptionMessageUI exceptionMessageUI = new ExceptionMessageUI();
            exceptionMessageUI.ErrorType = currentException.ErrorTypeDetail;
            exceptionMessageUI.ErrorDetailList = new List<ErrorDetail>();
            foreach (ClientError clientError in currentException.ClientErrorEntity)
            {
                ErrorDetail errorDetail = new ErrorDetail();
                errorDetail.ErrorCode = clientError.ErrorCode;
                errorDetail.ErrorMessage = clientError.ErrorMessage;
                exceptionMessageUI.ErrorDetailList.Add(errorDetail);
            }
            globalHttpContextMessage = JsonConvert.SerializeObject(exceptionMessageUI, Formatting.Indented);
        });
    }
    

这里ViewRClientException是我的自定义异常类,具有以下模式:

public class ViewRClientException : Exception
{
    public ViewRClientException(ErrorType errorType, List<ClientError> errorEntity)
    {
        ErrorTypeDetail = errorType;
        ClientErrorEntity = errorEntity;
    }
    public ErrorType ErrorTypeDetail { get; private set; }
    public List<ClientError> ClientErrorEntity { get; private set; }
}
上面定义的

Action方法确保我们获得相关的Json序列化字符串,它可以用作Json响应,类似于SystemExceptionAction对于任何通用异常的工作,它不是自定义的。事实上,我有许多其他自定义异常类别。当前过滤器修改HttpContext。响应

  • 在WebAPIConfig.cs中注册Exception过滤器,如下所示:

      public static class WebApiConfig
        {
          public static void Register(HttpConfiguration config)
          {
            // Web API configuration and services
            // Adding the Generic Exception Filter for the application
            config.Filters.Add(new ViewRExceptionFilterAttribute());
            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute("ControllerActionApi", "api/{controller}/{action}/{userID}",
                new {userID = RouteParameter.Optional}
                );
            config.Routes.MapHttpRoute("ControllerApi", "api/{controller}/{userID}",
                new {userID = RouteParameter.Optional}
                );
          }
       }
    
  • 现在它应该可以根据需要提供自定义消息

    不完整示例。ClientError,ErrorType ErrorTypeDetail

    如果你要贡献,请包括一切!