0

I am trying to understand custom exceptionhandlers but am not getting the hang of it. I tried implementing a custom exception handler like explained in the following pages:
https://www.exceptionnotfound.net/the-asp-net-web-api-exception-handling-pipeline-a-guided-tour/ https://learn.microsoft.com/en-us/aspnet/web-api/overview/error-handling/web-api-global-error-handling

Now my code is:

public class CustomRestErrorHandlerException : ExceptionHandler
{
    public void CustomError(String error)
    {
        var message = new HttpResponseMessage(HttpStatusCode.NoContent)
        {
            Content = new StringContent("An unknown error occurred saying" + error)
        };

        throw new HttpResponseException(message);
    }

    public override void Handle(ExceptionHandlerContext context)
    {
        if (context.Exception is ArgumentNullException)
        {
            var result = new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                Content = new StringContent(context.Exception.Message),
                ReasonPhrase = "ArgumentNullException"
            };

            context.Result = new ErrorMessageResult(context.Request, result);
        }
        else if (context.Exception is ArgumentException)
        {
            var result = new HttpResponseMessage(HttpStatusCode.NoContent)
            {
                Content = new StringContent(context.Exception.Message),
                ReasonPhrase = "Argument is not found"
            };

            context.Result = new ErrorMessageResult(context.Request, result);
        }
        else if (context.Exception is ArgumentOutOfRangeException)
        {
            var result = new HttpResponseMessage(HttpStatusCode.NotImplemented)
            {
                Content = new StringContent(context.Exception.Message),
                ReasonPhrase = "Argument is out of range"
            };

            context.Result = new ErrorMessageResult(context.Request, result);

        }
        else
        {
            CustomError(context.Exception.Message);
        }
    }

    public class ErrorMessageResult : IHttpActionResult
    {
        private HttpRequestMessage _request;
        private HttpResponseMessage _httpResponseMessage;

        public ErrorMessageResult(HttpRequestMessage request, HttpResponseMessage httpResponseMessage)
        {
            _request = request;
            _httpResponseMessage = httpResponseMessage;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(_httpResponseMessage);
        }
    }
}

Then I try to call the exceptionhandler which I obviously do wrong : (this I probably do not understand <<

    [Route("api/***/***")]
    [HttpGet]
    public IHttpActionResult Clear****()
    {
        try
        {
            // try clearing
        }
        catch(Exception e)
        {
            throw new CustomRestErrorHandlerException();     << error occurs here 
        }

        return this.Ok();
    }

As you can see the error occurs because the exception is not an exceptionhandler but I have no idea how to then throw an exception through an custom exception handler since it's explained nowhere.

Can anyone explain this to me with a small example perhaps?

Tvt
  • 223
  • 1
  • 3
  • 16

2 Answers2

0

Quote from: https://www.exceptionnotfound.net/the-asp-net-web-api-exception-handling-pipeline-a-guided-tour/:

"The handler, like the logger, must be registered in the Web API configuration. Note that we can only have one Exception Handler per application."

config.Services.Replace(typeof(IExceptionHandler), new CustomRestErrorHandlerException ()); 

So add the line above to the WebApiConfig.cs file and then simply throw an exception from the controller:

[Route("api/***/***")]
[HttpGet]
public IHttpActionResult Clear****()
{
    // do not use try catch here
    //try
    //{
        // try clearing
    //}
    //catch(Exception e)
    //{
        //throw new CustomRestErrorHandlerException();     << error occurs here 
    //}

    throw new Exception();
}
Dávid Molnár
  • 10,673
  • 7
  • 30
  • 55
0

ExceptionHandler's have to be registered in the Web API configuration. This can be done in the WebApiConfig.cs file as shown below, where config is of type System.Web.Http.HttpConfiguration.

config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());

Once they are registered they are automatically called during unhandled exceptions. To test it out you might want to throw an exception in the action method such as:

[Route("api/***/***")]
[HttpGet]
public IHttpActionResult Clear****()
{
    try
    {
        // try clearing
    }
    catch(Exception e)
    {
        throw new ArgumentNullException();     << error occurs here 
    }

    return this.Ok();
}

You can now put a breakpoint in your exception handler and see how the unhandled exception is caught by the global ExceptionHandler.

degant
  • 4,861
  • 1
  • 17
  • 29
  • So this means that i just throw the exception there and it works. even if it's Throw new exception(); But what if i just throw. Wil it also still handle the code then? – Tvt Apr 29 '17 at 13:14
  • @Tvt Yes everything will be caught by your exception handler. Then based on the exception type you can handle them differently. For example in case of an ArgumentNullException you can handle that in the global exception handler and change the response to a 400 BadRequest. – degant Apr 29 '17 at 13:19