<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=srinivas_vsk" rel="nofollow">srinivas kvs</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-7862?redirect=false" rel="nofollow">SPR-7862</a></strong> and commented</p>
<p dir="auto">When the <code class="notranslate">@ExceptionHandler</code> method returns a ResponseEntity, it throws IllegalArgument exception while returning the responsenetity object.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0.5</p>
<p dir="auto"><strong>Reference URL:</strong> <a href="http://forum.springsource.org/showthread.php?p=337899#post337899" rel="nofollow">http://forum.springsource.org/showthread.php?p=337899#post337899</a></p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=rajeev1982" rel="nofollow">Rajeev Sharma</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-7637?redirect=false" rel="nofollow">SPR-7637</a></strong> and commented</p>
<p dir="auto">I am new to Spring Framework. I am using <code class="notranslate">@ExceptionHandler</code> to handle exceptions in my controller. I thought the process of returning result from exception handler would be similar to a request handler but that is not the case. Below is my code.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@RequestMapping(value = &quot;/{userid}&quot;, method = RequestMethod.GET)
public @ResponseBody
User getUser(@PathVariable(value = &quot;userid&quot;) int userId) throws SpringTestException {
	logger.trace(&quot;Getting user: &quot; + userId);
	User user = getUserDAO().getUser(userId);
	if (user == null) {
		throw new SpringTestException(1000, &quot;User does not exists&quot;);
	}

	logger.trace(&quot;Userid: &quot; + user.getId() + &quot;, Name: &quot; + user.getName() + &quot;, Email: &quot;
			+ user.getEmailId());
	return user;
}"><pre class="notranslate"><code class="notranslate">@RequestMapping(value = "/{userid}", method = RequestMethod.GET)
public @ResponseBody
User getUser(@PathVariable(value = "userid") int userId) throws SpringTestException {
	logger.trace("Getting user: " + userId);
	User user = getUserDAO().getUser(userId);
	if (user == null) {
		throw new SpringTestException(1000, "User does not exists");
	}

	logger.trace("Userid: " + user.getId() + ", Name: " + user.getName() + ", Email: "
			+ user.getEmailId());
	return user;
}
</code></pre></div>
<p dir="auto">This code fetches user from the database and returns it to the user in json. But when the user is not found in db I through an exception which is handled by an exception class and supposed to return error message in json format ("code": 10000, "message": "user does not exists"}). Below is my exception handler version 1.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@ExceptionHandler(SpringTestException.class)
public @ResponseBody
HttpResponse handleSpringTestException(SpringTestException e) {
	logger.trace(&quot;Exception caught&quot;);
	return new HttpResponse(e.getCode(), e.getMessage());
}"><pre class="notranslate"><code class="notranslate">@ExceptionHandler(SpringTestException.class)
public @ResponseBody
HttpResponse handleSpringTestException(SpringTestException e) {
	logger.trace("Exception caught");
	return new HttpResponse(e.getCode(), e.getMessage());
}
</code></pre></div>
<p dir="auto">HttpResponse has two members "code" and "message".</p>
<p dir="auto">When I make a curl call, I didn't get the response, instead got an exception with http-status 500.</p>
<p dir="auto">&lt; HTTP/1.1 500 Internal Server Error<br>
&lt; Server: Apache-Coyote/1.1<br>
&lt; Content-Type: text/html;charset=utf-8<br>
&lt; Content-Length: 2960<br>
&lt; Date: Sun, 10 Oct 2010 12:35:33 GMT<br>
&lt; Connection: close<br>
&lt;</p>
<p dir="auto">&lt;html&gt;&lt;head&gt;&lt;title&gt;Apache Tomcat/6.0.20 - Error report&lt;/title&gt;&lt;style&gt;&lt;!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--&gt;&lt;/style&gt; &lt;/head&gt;&lt;body&gt;&lt;h1&gt;HTTP Status 500 - &lt;/h1&gt;&lt;HR size="1" noshade="noshade"&gt;&lt;p&gt;&lt;b&gt;type&lt;/b&gt; Exception report&lt;/p&gt;&lt;p&gt;&lt;b&gt;message&lt;/b&gt; &lt;u&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;description&lt;/b&gt; &lt;u&gt;The server encountered an internal error () that prevented it from fulfilling this request.&lt;/u&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;exception&lt;/b&gt; &lt;pre&gt;org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.ivasoft.springtest.common.SpringTestException: User does not exists<br>
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)<br>
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)<br>
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)<br>
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)<br>
&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;root cause&lt;/b&gt; &lt;pre&gt;com.ivasoft.springtest.common.SpringTestException: User does not exists<br>
com.ivasoft.springtest.controllers.UserControllerIoC.getUser(UserControllerIoC.java:43)<br>
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br>
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)<br>
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br>
java.lang.reflect.Method.invoke(Method.java:616)<br>
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)<br>
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:427)<br>
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)<br>
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:788)<br>
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:717)<br>
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)<br>
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)<br>
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)<br>
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)</p>
<ul dir="auto">
<li>Closing connection #0<br>
&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;note&lt;/b&gt; &lt;u&gt;The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.&lt;/u&gt;&lt;/p&gt;&lt;HR size="1" noshade="noshade"&gt;&lt;h3&gt;Apache Tomcat/6.0.20&lt;/h3&gt;&lt;/body&gt;&lt;/html&gt;</li>
</ul>
<p dir="auto">I googled around for hours and found that ExceptionHandlers are handled by different Adaptor than that of request handlers so I need to configure something in my xml file. I did this in my xml config file.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;bean id=&quot;stringHttpMessageConverter&quot;
	class=&quot;org.springframework.http.converter.StringHttpMessageConverter&quot; /&gt;

&lt;bean id=&quot;jsonHttpMessageConverter&quot;
	class=&quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&quot; /&gt;

&lt;bean id=&quot;methodHandlerExceptionResolver&quot;
	class=&quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&quot;&gt;
	&lt;property name=&quot;messageConverters&quot;&gt;
		&lt;list&gt;
			&lt;ref bean=&quot;stringHttpMessageConverter&quot; /&gt;
			&lt;ref bean=&quot;jsonHttpMessageConverter&quot; /&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;"><pre class="notranslate"><code class="notranslate">&lt;bean id="stringHttpMessageConverter"
	class="org.springframework.http.converter.StringHttpMessageConverter" /&gt;

&lt;bean id="jsonHttpMessageConverter"
	class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /&gt;

&lt;bean id="methodHandlerExceptionResolver"
	class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver"&gt;
	&lt;property name="messageConverters"&gt;
		&lt;list&gt;
			&lt;ref bean="stringHttpMessageConverter" /&gt;
			&lt;ref bean="jsonHttpMessageConverter" /&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;
</code></pre></div>
<p dir="auto">I got this response after configurations change (This is what I expected):</p>
<p dir="auto">&lt; HTTP/1.1 200 OK<br>
&lt; Server: Apache-Coyote/1.1<br>
&lt; Content-Type: application/json<br>
&lt; Transfer-Encoding: chunked<br>
&lt; Date: Sun, 10 Oct 2010 12:37:43 GMT<br>
&lt;</p>
<ul dir="auto">
<li>Connection #0 to host localhost left intact</li>
<li>Closing connection #0<br>
{"message":"User does not exists","code":1000}</li>
</ul>
<p dir="auto">I don't know if the above configuration is correct (This is working but could be a hack found by some developer) as I found it in some forum.</p>
<p dir="auto">Second level problem came when I used ResposeEntity as return value for my exception handler. I changed the exception handler to this</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@ExceptionHandler(SpringTestException.class)
public @ResponseBody
ResponseEntity&lt;HttpResponse&gt; handleSpringTestException(SpringTestException e) {
	return new ResponseEntity&lt;HttpResponse&gt;(new HttpResponse(e.getCode(), e.getMessage()),
			HttpStatus.NOT_FOUND);
}"><pre class="notranslate"><code class="notranslate">@ExceptionHandler(SpringTestException.class)
public @ResponseBody
ResponseEntity&lt;HttpResponse&gt; handleSpringTestException(SpringTestException e) {
	return new ResponseEntity&lt;HttpResponse&gt;(new HttpResponse(e.getCode(), e.getMessage()),
			HttpStatus.NOT_FOUND);
}
</code></pre></div>
<p dir="auto">And I was exception the same response with status code 404, but got this response.</p>
<p dir="auto">&lt; HTTP/1.1 200 OK<br>
&lt; Server: Apache-Coyote/1.1<br>
&lt; Content-Type: application/json<br>
&lt; Transfer-Encoding: chunked<br>
&lt; Date: Sun, 10 Oct 2010 12:39:13 GMT<br>
&lt;</p>
<ul dir="auto">
<li>Connection #0 to host localhost left intact</li>
<li>Closing connection #0<br>
{"statusCode":"NOT_FOUND","headers":{},"body":{"message":"User does not exists","code":1000}}</li>
</ul>
<p dir="auto">Looks like the exception handlers behave differently that request handlers. I fail to understand why is it that way. I used following code to get required results.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@ExceptionHandler(SpringTestException.class)
public @ResponseBody
HttpResponse handleSpringTestException(SpringTestException e, HttpServletResponse response) {
	logger.trace(&quot;Exception caught&quot;);
	response.setStatus(HttpServletResponse.SC_NOT_FOUND);
	return new HttpResponse(e.getCode(), e.getMessage());
}"><pre class="notranslate"><code class="notranslate">@ExceptionHandler(SpringTestException.class)
public @ResponseBody
HttpResponse handleSpringTestException(SpringTestException e, HttpServletResponse response) {
	logger.trace("Exception caught");
	response.setStatus(HttpServletResponse.SC_NOT_FOUND);
	return new HttpResponse(e.getCode(), e.getMessage());
}
</code></pre></div>
<p dir="auto">This makes my code dependent on HttpServletResponse object and this is not the same as what I would do in a request handler. I could use <code class="notranslate">@ResponseBody</code> ResponseEntity as return value to get the same result and that seems correct to me. If exception handlers and request handlers behave the same way it would be much easier and consistent for the framework to work with.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0.4</p>
<p dir="auto">2 votes, 2 watchers</p>