I had checked this link http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling. In this link they mentioned like this
class OopsExceptionHandler : ExceptionHandler { public override void HandleCore(ExceptionHandlerContext context) { context.Result = new TextPlainErrorResult { Request = context.ExceptionContext.Request, Content = "Oops! Sorry! Something went wrong." + "Please contact [email protected] so we can try to fix it." }; } private class TextPlainErrorResult : IHttpActionResult { public HttpRequestMessage Request { get; set; } public string Content { get; set; } public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.InternalServerError); response.Content = new StringContent(Content); response.RequestMessage = Request; return Task.FromResult(response); } } }
I don't know how to call this class in my Web API actions. So can any one give me the complete sample using this ExceptionHandler
.
You can customize how Web API handles exceptions by writing an exception filter. An exception filter is executed when a controller method throws any unhandled exception that is not an HttpResponseException exception.
Global Exception Filters With exception filters, you can customize how your Web API handles several exceptions by writing the exception filter class. Exception filters catch the unhandled exceptions in Web API. When an action method throws an unhandled exception, execution of the filter occurs.
What you have in your code snippet should work. The server will send back a 404 Not Found to the client if test is null with no response body. If you want a response body, you should consider using Request. CreateErrorResponse as explained in the blog post above and passing that response to the HttpResponseException .
Instead, you can simply inherit from ExceptionHandler and override the Handle method.
public class MyExceptionHandler: ExceptionHandler { public override void Handle(ExceptionHandlerContext context) { //TODO: Do what you need to do base.Handle(context); } }
ExceptionHandler implements IExceptionHandler and manage basic core mechanisms (like async and that exception should be handled or not).
Use your exception handler like that:
config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());
This page explains how to implements IExceptionHandler, but there are some typos and the code does not reflect the latest version of WebApi.
There is no documentation about the System.Web.Http.ExceptionHandling
namespace (a little bit on NuDoq).
So.. using a .NET assembly decompiler having a look at the source code on GitHub, I saw the ExceptionHandler
class which implements IExceptionHandler
and have some virtual methods.
ExceptionHandler looks like that:
namespace System.Web.Http.ExceptionHandling { /// <summary>Represents an unhandled exception handler.</summary> public abstract class ExceptionHandler: IExceptionHandler { /// <returns>Returns <see cref="T:System.Threading.Tasks.Task" />.</returns> Task IExceptionHandler.HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) { if (context == null) { throw new ArgumentNullException("context"); } ExceptionContext arg_14_0 = context.ExceptionContext; if (!this.ShouldHandle(context)) { return TaskHelpers.Completed(); } return this.HandleAsync(context, cancellationToken); } /// <summary>When overridden in a derived class, handles the exception asynchronously.</summary> /// <returns>A task representing the asynchronous exception handling operation.</returns> /// <param name="context">The exception handler context.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> public virtual Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) { this.Handle(context); return TaskHelpers.Completed(); } /// <summary>When overridden in a derived class, handles the exception synchronously.</summary> /// <param name="context">The exception handler context.</param> public virtual void Handle(ExceptionHandlerContext context) { } /// <summary>Determines whether the exception should be handled.</summary> /// <returns>true if the exception should be handled; otherwise, false.</returns> /// <param name="context">The exception handler context.</param> public virtual bool ShouldHandle(ExceptionHandlerContext context) { if (context == null) { throw new ArgumentNullException("context"); } ExceptionContext exceptionContext = context.ExceptionContext; ExceptionContextCatchBlock catchBlock = exceptionContext.CatchBlock; return catchBlock.IsTopLevel; } } }
You can clearly see that ShouldHandle
is implemented using ExceptionContextCatchBlock.IsTopLevel
and that HandleAsync
calls Handle
:)
I hope this will helps until complete documentation shows up.
In your WebApi config your need to add the line:
config.Services.Replace(typeof (IExceptionHandler), new OopsExceptionHandler());
Also make sure you have created the base ExceptionHandler class that implements IExceptionHandler:
public class ExceptionHandler : IExceptionHandler { public virtual Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) { if (!ShouldHandle(context)) { return Task.FromResult(0); } return HandleAsyncCore(context, cancellationToken); } public virtual Task HandleAsyncCore(ExceptionHandlerContext context, CancellationToken cancellationToken) { HandleCore(context); return Task.FromResult(0); } public virtual void HandleCore(ExceptionHandlerContext context) { } public virtual bool ShouldHandle(ExceptionHandlerContext context) { return context.CatchBlock.IsTopLevel; } }
Note that this will only deal with exceptions that are not handled elsewhere (e.g. by Exception filters).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With