使用HttpError丢失异常信息

时间:2015-09-24 09:37:02

标签: c# asp.net .net asp.net-web-api

当通过应用程序引发异常时,我正在尝试将自定义errorid(散列guid)添加到HttpError。因此,诸如“xxxxxx - error”之类的消息将传递给客户端。

我们有一个自定义ExceptionFilterAttribute来捕获和记录异常:

public class ExceptionFilter : ExceptionFilterAttribute
{
    ...
    public override void OnException(HttpActionExecutedContext context)
    {
        Guid guid = Guid.NewGuid();
        context.Exception.Data.Add("guid", guid);
        _log.WriteEvent(message, context.Exception, guid);
    }
}

自定义MediaTypeFormatter将此(以及其他类型)作为json发送回客户端:

public class DotNetJsonFormatter : MediaTypeFormatter
{
    ...
    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
    {
        return Task.Factory.StartNew(() =>
        {
            if (typeof(Exception).IsAssignableFrom(type)) {
                // write a json string to the stream containing the message and id
            } else if (typeof(HttpError).IsAssignableFrom(type)) {
                // write a json string to the stream containing the message and id
            }
        });
    }
}

我的问题在于HttpError - 它包含的是一个包含消息,类型,堆栈跟踪等的字典 - 我认为设置数据可能会通过(我检查了HttpError构造函数,这就是所有的从例外中撤出。)

  • 我无法重写应用程序以抛出自定义异常,因此id最终会显示在消息中。
  • 我可以'使用反射,更改异常消息以在过滤器中包含id但是感觉很乱。
  • 考虑在过滤器的消息中重新抛出一个带有id的新异常,但这似乎完全绕过了格式化程序
  • 尝试设置过滤器的Exception属性以设置基础异常,但它没有任何效果。

我是否坚持使用reflection technique

1 个答案:

答案 0 :(得分:0)

我讨厌回答我自己的问题,但无论如何我都会。

所以我没有考虑的一个选项(在盒子内部思考太多)是在过滤器中设置响应而不是让格式化器处理它。

更新过滤器:

public class ExceptionFilter : ExceptionFilterAttribute
{
    public ExceptionFilter(ILogger log, IClientExceptionFormatter exceptionFormatter)
    {
        ...
        _log = log;
        _exceptionFormatter = exceptionFormatter;
    }

    public override void OnException(HttpActionExecutedContext context)
    {
        ...
        _log.Error(context.Exception);
        context.Response = new ExceptionJsonResponse(context.Exception, _exceptionFormatter);
    }
    ...
}

ExceptionJsonResponse类:

public class ExceptionJsonResponse : HttpResponseMessage
{
    public ExceptionJsonResponse(Exception exception, IClientExceptionFormatter formatter)
    {
        ...
        _exception = exception;
        _formatter = formatter;

        Content = CreateContent();
        StatusCode = HttpStatusCode.InternalServerError;
    }

    private HttpContent CreateContent()
    {
        HttpContent content = new StringContent(_formatter.GetJson(_exception));
        content.Headers.ContentType = new MediaTypeHeaderValue(Common.ContentType.ApplicationJson);
        return content;
    }
    ...
}

这样可能会绕过格式化程序,因为响应是HttpResponseMessage。然后,我可以将客户端消息更改为我的内容。