6

In my MVC WebApi service, when an exception is thrown, it is handled by a filter:

public class GlobalExceptionFilter : ExceptionFilterAttribute {
    public override void OnException(HttpActionExecutedContext context) {
        context.Response = context.Request.CreateErrorResponse(HttpStatusCode.BadRequest, 
                                                               "Bad Request", 
                                                               context.Exception);
    } 
}

This HTTP response generated by this filter is dependent on config.IncludeErrorDetailPolicy configuration.

If I set config.IncludeErrorDetailPolicy to IncludeErrorDetailPolicy.Always, all the details are serialized into the HTTP response (Message, ExceptionMessage, ExceptionType, and StackTrace).

If I set config.IncludeErrorDetailPolicy to IncludeErrorDetailPolicy.Never, only the Message is included.

However, I want to include the Message, ExceptionMessage, and ExceptionType in the HTTP response but not the StackTrace; how do I exclude only the StackTrace? Or should I just concatenate the needed details into the Message field?

To add some context to my question, the client needs these exception details to handle special cases...but never the stack trace.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
Bill Heitstuman
  • 979
  • 1
  • 8
  • 23

2 Answers2

8

Thanks for pointing me in the right direction Leon. Your link inspired my solution below. It keeps the functionality of the CreateErrorResponse method and appends the ExceptionMessage and ExceptionType attributes.

public class GlobalExceptionFilter : ExceptionFilterAttribute {
    public override void OnException(HttpActionExecutedContext context) {
        context.Response = context.Request.CreateErrorResponse(HttpStatusCode.BadRequest, 
                                                               "Bad Request", 
                                                               context.Exception);
            var httpError = (HttpError)((ObjectContent<HttpError>)context.Response.Content).Value;
            if (!httpError.ContainsKey("ExceptionType"))
                httpError.Add("ExceptionType", context.Exception.GetType().FullName);
            if (!httpError.ContainsKey("ExceptionMessage"))
                httpError.Add("ExceptionMessage", context.Exception.Message);
    } 
}
Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126
Bill Heitstuman
  • 979
  • 1
  • 8
  • 23
2

Concatenate: no

Override and extend: yes

Take a look at the accepted answer here: Return custom error objects in Web API

and more information (in general) here: Throw HttpResponseException or return Request.CreateErrorResponse?

Community
  • 1
  • 1
Leon
  • 919
  • 6
  • 21
  • So basically, I have to re-implement the CreateErrorResponse method and consider the IncludeErrorDetailPolicy options. I was hope for a configuration somewhere. – Bill Heitstuman Dec 10 '14 at 05:08
  • Actually no. See the valid answer in the link I've given. Create a new filter. Register that filter and bind your class to that new filter. The filter will *filter* your message before it's being used. :: public class GlobalExceptionFilter : ExceptionFilterAttribute >> becomes public class GlobalExceptionFilter : MyNewFilterAttributeThingyHere – Leon Dec 10 '14 at 06:18
  • I think you are misunderstanding my goal. I don't want the HTTP response to contain custom exception attributes. Rather, I want it to work like the `CreateErrorResponse` method but with always include `ExceptionMessage`, `ExceptionType` attributes. – Bill Heitstuman Dec 11 '14 at 04:27