IExceptionHandler does not handle UnsupportedMediaTypeException - asp.net

I have implemented an exception handler (IExceptionHandler). Its HandleAsync method is called when exceptions are thrown inside controllers.
However, when a wrong content-type is passed with the request and an UnsupportedMediaTypeException is thrown in the formatter, my handler is not called. Instead the default error message is returned
{
"Message": "The request entity's media type...
"ExceptionMessage": "No MediaTypeFormatter ...
...
}
I would like to handle ALL exceptions. What am I missing here?

You need to catch it with a global ExceptionFilterAttribute, and filter HttpResponseException, not UnsupportedMediaTypeException.
E.g.
httpConfiguration.Filters.Add(new MyHttpResponseExceptionFilterAttribute());
It turns out that UnsupportedMediaTypeException is actually wrapped up in an HttpResponseException by the time it hits the WebApi pipeline.
HttpResponseException is not intercepted by IExceptionHandler, because it is designed to transport an HttpResponsMessage out to the client. The UnsupportedMediaTypeException is automatically wrapped into an HttpResponsMessage by the framework, and thrown in a HttpResponseException. The message you see in the HTTP response says "UnsupportedMediaTypeException", but that is actually just the Content of the HttpResponsMessage (HttpResponseException.Response.Content).

Related

How can I return a custom reponse for a bean validation error under Open Liberty?

We are using beanValidation-2.0 and cdi-2.0 under Open Liberty 20.0.0.3. This works fine in that Open Liberty returns a 400 Bad Request response containing the bean validation error message when a a bean validation error is detected. I would like to update our application to instead return a custom response when Open Liberty detects a bean validation error. Is there a way that I can somehow "intercept" the bean validation error (or the Open Liberty generated response) and return my own custom response?`
Usually when you get a validation error, a ConstraintViolationException is thrown and you should be able to catch that and create your own response.
If you're using JAX-RS, you might want to do this by creating and registering an ExceptionMapper to handle this type of exception and turn it into a response. There's an example here.
You might be able to do this with a custom MessageInterpolator.
It can be specified via the message-interpolator element of validation.xml.

How to get the HTTP-Status from a webMethods com.wm.net.NetException?

How to get the HTTP-Status from a webMethods com.wm.net.NetException?
Is there a way to get the http status code from within the catch block of a java service after calling the pub.client:http service?
If you invoke the pub.client:http from within a flow service, you'll notice that it doesn't throw an exception. For example, a "403 Forbidden" error, will not throw an exception. Instead, it will output to the pipeline a header document.
Within the header document you will find the http status:
When you invoke pub.client:http from within a java service then the invocation is suppose to return an IData object. From that object you should be able to extract the status field using IDataUtil.
So, when you evaluate that the status is not OK, you can throw a ServiceException which will be caught by the flow try/catch.
Hope this helps!

How to handle Incorrect JSON syntax in Spring MVC

I have a spring MVC Project, wherein I need to handle incorrect JSON syntax.
Spring MVC throws an error as text/html, which looks like:
Apache Tomcat/7.0.47 - Error report HTTP Status 400 - type Status reportmessage description The request sent by the client was syntactically incorrect.Apache Tomcat/7.0.47
However I want to throw my own exception in JSON format.
Is there any way to do it?
Thanks
I just ran into this as well, here's what I found to fix it:
The Spring MVC docs reference HttpMessageConverter as responsible for converting a #ResponseBody. For JSON, you're likely using a MappingJackson2HttpMessageConverter, which when attempting to convert a message can throw a HttpMessageNotReadableException.
If you have some form of exception handler for that, you can intercept the 400 response.
You can debug to see which Exception is actually thrown (might be a TypeMismatchException or something like that). Then, you can specify an error handler in your controller like
#ExceptionHandler(TypeMismatchException.class)
public String handleTypeMismatchException(TypeMismatchException ex) {
}
Now, in this controller method you can do whatever you want, like passing it the model, request, response etc. You can send to a view, redirect or in your case use a ResponseBody or however else you would like to serve your JSON error.

How do I trap a SerializationException in Web API?

I have an ASP.NET Web API web service which throws a SerializationException in certain circumstances. The problem is that I'm unable to trap and log this exception server-side -- the only place it shows up is in the body of the HTTP response to the client.
I registered an ExceptionFilterAttribute as described in Exception Handling in ASP.NET Web API and verified that it works properly when I throw an exception within my controller. Unfortunately the SerializationException is being thrown during the response (after the controller) and appears to be completely swallowed up by ASP.NET. I also tried hooking Application_Error() in Global.asax.cs but it didn't show up there either.
How can I catch SerializationException exceptions during the Web API response?
If, instead of returning an object, you use the ApiController.CreateResponse() method and return a HttpResponseMessage you can then do response.Content.LoadIntoBufferAsync().Wait() and that will force the serialization to happen whilst you are still in the action and therefore can catch the exception.
BTW, Serialization of responses actually happens at the host layers(in HttpControllerHandler, when hosted in IIS and in HttpSelfhostServer, when hosted in SelfHost) which is way below the stack and not immediately after the response is returned from an action.
WebAPI Stack Poster: http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster-grayscale.pdf
That said, I am not able to come up with a straight forward way to achieve this. This is cumbersome, but may be override the default Xml and Json formatter's WriteToStreamAsync methods and try-catch-log any exceptions?
Alternatively, you can enable Web API Tracing which would log the exceptions happening during serialization. But yeah, if you do not know for the requests which cause the serialization errors, then you might want to enable tracing all the time which i am not sure is something you might want to do.
You can catch all Web API exceptions by registering an implementation of IExceptionHandler.
See Web API Global Error Handling
...there are a number of cases that exception filters can’t handle. For example:
Exceptions thrown from controller constructors.
Exceptions thrown from message handlers.
Exceptions thrown during routing.
Exceptions thrown during response content serialization .
One thing not mentioned in that article is that your IExceptionHandler must be registered, either by GlobalConfiguration.Configuration.Services.Add(...) or via an IoC container configured to be used by DependencyResolver.

Propagating AccessDeniedException in Spring Security

In my web application I am using Spring Security and Spring MVC.
I have secured a couple of methods with #Secured annotation and configured Spring Security in such a way that when one of those methods is accessed without the proper role, the user is taken to the login page. However, I do not want that behaviour when the offending request comes from Ajax, so I implemented the custom #ExceptionHandler annotated method to determine the request's context.
This is my exception handler:
#ExceptionHandler(AccessDeniedException.class)
public void handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (isAjax(request)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
throw ex;
}
}
This way I can both handle the exception myself (for example, log an attempt of accessing the #Secured method) and then let Spring do its part and redirect the user to the login page by rethrowing the AccessDeniedException. Also, when the request comes from Ajax I set the response status to SC_UNAUTHORIZED and handle the error on the client side.
Now, this seems to be working fine, but I am getting the following ERROR each time I rethrow the exception from the handleAccessDeniedException method:
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke #ExceptionHandler method: public void app.controller.BaseController.handleAccessDeniedException(org.springframework.security.access.AccessDeniedException,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception
org.springframework.security.access.AccessDeniedException:
at app.controller.BaseController.handleAccessDeniedException(BaseController.java:23)
at app.controller.BaseController$$FastClassByCGLIB$$8f052058.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
(...)
I have not added any exception handling specifics to spring xml configuration files.
I do not see any issues with the app itself, but the error is there and since I am quite new to Spring MVC and Spring Security, I am guessing that I am not doing this properly. Any suggestions? Thanks!
Your exception handler isn't supposed to throw another exception. It's supposed to deal with it and send a response. It's a good idea to check the code if you get an error from a class to see how it behaves.
For the non-ajax case, you'd be better to redirect the response to the login page, if that's what you want. Alternatively, you can customize the AuthenticationEntryPoint used by Spring Security instead and omit AccessDeniedExceptions from MVC handling. The behaviour would essentially be the same as the defaul LoginUrlAuthenticationEntryPoint but you would extend it to return a 403 when an ajax request is detected.

Resources