aleczandru
aleczandru

Reputation: 5449

CreateErrorResponse does not override Exception stacktrace and message

Hi I am creating an exception handling mechanisem in asp.net WebApi and I am confused about how the returned response message is created.Here is my code:

public class ExceptionHandlerAttribute : ExceptionFilterAttribute  
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.Accepted, new HttpError
        {
            { "Message" , "I am error"},
            { "StatusCode" , "20"}
        });
    }
}

     [AllowAnonymous]
    [HttpPost]
    [Validate]
    public IHttpActionResult Register(UserModel userRegistrationModel)
    {
        throw new AccessDeniedException("message" , new Exception("inner exception"));
    }

 public class AccessDeniedException : BaseException
{
    public AccessDeniedException(string message, Exception exception)
        : base(message, exception)
    {

    }
}

  public class BaseException : Exception
{
    public BaseException(string message , Exception exception) : base(message , exception)
    {

    }
}

Now I have registered the ExceptionHandlerAttributed in myfilter config and while debugging I realized that code in the method OnException runs.

The problem is that the response is this one:

"readyState": 4,
"responseText": "{\"message\":\"An error has occurred.\",\"exceptionMessage\":\"message\",\"exceptionType\":\"CodeArt.Common.Exceptions.AccessDeniedException\",\"stackTrace\":\"   at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\\r\\n--- End of stack trace from previous location where exception was thrown ---\\r\\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\\r\\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\\r\\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\\r\\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()\",\"innerException\":{\"message\":\"An error has occurred.\",\"exceptionMessage\":\"inner exception\",\"exceptionType\":\"System.Exception\",\"stackTrace\":null}}",
"responseJSON": {
    "message": "An error has occurred.",
    "exceptionMessage": "message",
    "exceptionType": "CodeArt.Common.Exceptions.AccessDeniedException",
    "stackTrace": "   at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()",
    "innerException": {
        "message": "An error has occurred.",
        "exceptionMessage": "inner exception",
        "exceptionType": "System.Exception",
        "stackTrace": null
    }
},
"status": 500,
"statusText": "Internal Server Error"

I was hopping of not sending the exception stacktrace and anything else related to the exception.All I wanted to send was the data set in the OnException method.

What I am doing wrong?

Upvotes: 3

Views: 1102

Answers (1)

Aliostad
Aliostad

Reputation: 81660

You have to add the filter to global filters and set the response to the instance of response created:

actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.Accepted, new HttpError
    {
        { "Message" , "I am error"},
        { "StatusCode" , "20"}
    });

Just beware of the issue I raised a while back regarding non-consumed responses resulting in memory leak. Hence, you need to first do this:

if(actionExecutedContext.Response != null)
    actionExecutedContext.Response.Dispose();

and then

actionExecutedContext.Response =  ...

Upvotes: 5

Related Questions