简体   繁体   English

使用HttpError丢失异常信息

[英]Losing Exception information with HttpError

I'm trying to get a custom errorid (hashed guid) to an HttpError when exceptions are raised through an application. 当通过应用程序引发异常时,我正在尝试为HttpError获取自定义的errorid(哈希的guid)。 So a message like "xxxxxx - error" is passed to the client. 因此,诸如“ xxxxxx-错误”之类的消息将传递给客户端。

We have a custom ExceptionFilterAttribute to catch and log exceptions: 我们有一个自定义的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);
    }
}

A custom MediaTypeFormatter to send this (among other types) as json back to the client: 一个自定义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
            }
        });
    }
}

My problem lies with HttpError - all it contains is a dictionary containing the message, type, stack trace etc - I thought setting the data might pull this through (I've checked the HttpError constructor and that's all that's pulled from the exception). 我的问题出在HttpError -它所包含的只是一个字典,其中包含消息,类型,堆栈跟踪等-我认为设置数据可能会克服这个问题(我检查了HttpError构造函数,这就是从异常中提取的全部内容)。

  • I can't re-write the application to throw custom exceptions so the id ends up in the message. 我无法重新编写应用程序以引发自定义异常,因此ID最终出现在消息中。
  • I 'could' using reflection, alter the exception message to contain the id in the filter but it feels hacky. 我“可以”使用反射,更改异常消息以将ID包含在过滤器中,但感觉很hack。
  • Thought about re-throwing a new exception with the id in the message from the filter but this seems to bypass the formatter altogether 考虑过重新抛出来自过滤器的消息中带有id的新异常,但这似乎完全绕开了格式化程序
  • Tried setting the Exception property of the filter to set the underlying exception but it has no effect. 尝试设置过滤器的Exception属性以设置基础异常,但无效。

Am I stuck with the reflection technique ? 我会坚持使用反射技术吗?

I hate answering my own questions but I will anyway. 我讨厌回答我自己的问题,但我还是会的。

So one option I didn't consider (too much inside box thinking) was setting the response in the filter rather than letting the formatter handle it. 因此,我没有考虑的一种选择(过多的内部思考)是在过滤器中设置响应,而不是让格式化程序处理它。

The updated filter: 更新的过滤器:

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);
    }
    ...
}

The ExceptionJsonResponse class: 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;
    }
    ...
}

This way bypasses the formatter probably because the response is a HttpResponseMessage. 这种方式可能绕过了格式化程序,可能是因为响应是一个HttpResponseMessage。 I can then alter the client message to my hearts content. 然后,我可以将客户消息更改为我喜欢的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM