Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Integration returns 500 error instead of 400 error #3283

Closed
pavden opened this issue May 19, 2020 · 1 comment · Fixed by #3289
Closed

Spring Integration returns 500 error instead of 400 error #3283

pavden opened this issue May 19, 2020 · 1 comment · Fixed by #3289
Assignees
Milestone

Comments

@pavden
Copy link

pavden commented May 19, 2020

It was recommended by @artembilan to raise this issue as a result of respective stackoverflow topic.

This issue relates to error handling in Spring Integration when using its DefaultResponseErrorHandler class for outbound gateway.

At the moment everything works fine for xml-config defined below except returning actual error code. For example, when I call ${http.url}/profiles?pid={pid} with non-existing parameter pid instead of correct call ${http.url}/profiles?vin={vin} with existing parameter vin, I always get 500-error (Internal Server Error) instead of expected 400-error (Bad Request).

Example of xml-config:

<int-http:inbound-gateway id="service.rest.profiles"
                          request-channel="service.rest.profilesChannel"
                          path="/profiles"
                          payload-expression="#requestParams.vin"
                          message-converters="service.rest.jsonMessageConverter"
                          header-mapper="service.rest.headerMapper"
                          error-channel="service.rest.httpErrorInputChannel"
                          reply-channel="service.rest.httpResponseChannel"
                          supported-methods="GET"/>

<int:channel id="service.rest.profilesChannel"/>

<int:service-activator input-channel="service.rest.profilesChannel"
                       ref="service.rest.profileRestService" method="getProfiles"/>

-----------------------------------------------------------------------------------

<bean id="api.rest.errorHandler"
      class="org.springframework.web.client.DefaultResponseErrorHandler"/>

..........

<int:channel id="api.json.rest.profilesChannel"/>

<int-http:outbound-gateway
        url="${http.url}/profiles?vin={vin}"
        request-channel="api.json.rest.profilesChannel"
        http-method="GET"
        message-converters="api.rest.jsonMessageConverter"
        header-mapper="api.rest.headerMapper"
        error-handler="api.rest.errorHandler"
        expected-response-type="com.example.ProfilesResponse">
    <int-http:uri-variable name="vin" expression="payload"/>
</int-http:outbound-gateway>

For mentioned above 500-error I'm getting the following record in the log file:

19-May-2020 15:12:37.665 SEVERE [http-nio-8080-exec-8] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcherServlet] in context with path [/service-rest] threw exception
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'pid' cannot be found on object of type 'org.springframework.util.LinkedMultiValueMap' - maybe not public or not valid?
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:51)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:406)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:90)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:109)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:265)
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:309)
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:253)
    at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:112)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:53)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:128)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:103)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:121)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
@pavden pavden added status: waiting-for-triage The issue need to be evaluated and its future decided type: bug labels May 19, 2020
@artembilan artembilan added this to the 5.4 M1 milestone May 20, 2020
@artembilan artembilan added in: http and removed status: waiting-for-triage The issue need to be evaluated and its future decided labels May 20, 2020
@artembilan
Copy link
Member

I think even if we fix it the proper way it cannot be back-ported. Braking change in the behavior. Probably someone in the existing applications rely already on a bug...

@artembilan artembilan self-assigned this May 21, 2020
artembilan added a commit to artembilan/spring-integration that referenced this issue May 22, 2020
Fixes spring-projects#3283

* Process all the request message preparation exceptions
in the provided error channel to let target application
to make a decision about an appropriate HTTP status instead of
default 500 Server Error
garyrussell added a commit that referenced this issue May 28, 2020
* GH-3283: HTTP Inbound handle SpEL errors

Fixes #3283

* Process all the request message preparation exceptions
in the provided error channel to let target application
to make a decision about an appropriate HTTP status instead of
default 500 Server Error

* * Rephrase `ResponseStatusException` doc in the http.adoc

Co-authored-by: Gary Russell <grussell@vmware.com>

Co-authored-by: Gary Russell <grussell@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants