Announcement Announcement Module
No announcement yet.
async Proxied Service Methods w/ return values don't work with error channel Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • async Proxied Service Methods w/ return values don't work with error channel


    I've made several posts on this topic. In the interim I've done some more prototyping and debugging to learn more about this and provide greater detail.

    1. My initial prototype would exit before the errorChannel could be polled. I've fixed that and the errorChannel works properly for void @Gateway methods.

    However, if I define an async flow with an @Gateway on a method that returns some value, then there is a TypeConversion exception that is thrown after some endpoint in the flow throws an Exception. It looks like the conversion is attempting to convert the exception that is thrown, to the type that the @Gateway method declares as a return value. It doesn't look like the errorChannel is ever notified of the exception.

    Below is the stack trace:

    [java] Exception in thread "main" org.springframework.beans.ConversionNotSupportedEx ception: Failed to convert val
    e of type 'org.springframework.integration.message.MessageHa ndlingException' to required type 'com.traveltripper.starga
    er.intg.msg.ReservationDetails'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org
    springframework.integration.message.MessageHandlin gException] to required type [com.traveltripper.stargazer.intg.msg.Re
    ervationDetails]: no matching editors or conversion strategy found
    [java] at org.springframework.beans.SimpleTypeConverter.conv ertIfNecessary(
    [java] at org.springframework.beans.SimpleTypeConverter.conv ertIfNecessary(
    [java] at org.springframework.integration.gateway.GatewayPro xyFactoryBean.invokeGatewayMethod(GatewayProxyFact
    [java] at org.springframework.integration.gateway.GatewayPro xyFactoryBean.invoke(
    [java] at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(
    [java] at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(
    [java] at $Proxy6.testThrowCheckedExceptionAsyncTwo(Unknown Source)
    [java] at com.traveltripper.stargazer.intg.svc.proto.StubInt egrationServiceImpl.testThrowCheckedExceptionAsync Two(
    [java] at com.traveltripper.stargazer.intg.svc.proto.Service Client.forceCheckedExceptionWithSvcReturnValue(Ser
    [java] at com.traveltripper.stargazer.intg.svc.proto.Service Client.testErrorChannelWithSvcMethodReturn(Service
    [java] at com.traveltripper.stargazer.intg.svc.proto.Service Client.main(
    [java] Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.springframework.integration.m
    ssage.MessageHandlingException] to required type [com.traveltripper.stargazer.intg.msg.ReservationDe tails]: no matching
    editors or conversion strategy found
    [java] at nvertIfNecessary(
    [java] at nvertIfNecessary(
    [java] at org.springframework.beans.SimpleTypeConverter.conv ertIfNecessary(

  • #2
    Quick question
    What version of SI are you using?


    • #3
      Spring 1.0.4.

      Is this a known issue?


      • #4
        Spring Integration 1.0.4 that is


        • #5
          Yes, and it was fixed in 2.0. I would suggest to upgrade since we are at 2.0.RC1 and are in the final starches for GA release (few more weeks)


          • #6
            We might be able to backport the fix for 1.0.5 as well.

            Oleg, can you remind me exactly which issue it was?



            • #7


              • #8
                Thanks Oleg.

                As far as I can tell, this one issue, if backported to 1.0.x, would be sufficient to handle the particular issue:

                @ddo: can you please verify?



                • #9

                  Yes. This sounds like the fix to GenericMessage will solve my problem as long as this also caused the execution path to not notify the errorChannel of my exception.

                  Today, after copious meetings, I plan to download 2.0 and check out the new features in terms of RESTful support and I'll also see if this bug solves both of the issues I observed here.

                  If you want, I can report back to you before you do the backport. Might save you some time. It is a bit of a tough road where I am at to convince people to use non GA releases of software. The backport to 1.5 would be good for me in that regard.

                  I'll let you know what I find out about this in 2.0. Though, I won't get to this until this evening and hopefully I won't have any major xml re-jiggering to do.

                  Thanks Guys!


                  • #10
                    Great. Please do keep us up-to-date.

                    As far as 2.0 is concerned, we do plan to have GA by the end of the month.



                    • #11

                      I finished the upgrade to 2.0. The bug is only partially fixed, or there were two bugs.

                      I no longer get the type conversion exception, but the exception is not routed to the errorChannel. The exception just propogates up the call stack. This is not the expected behavior of asynchronous channels/handlers.

                      The documentation indicates that for asynchronous channels, exceptions are by default routed to this channel. I have a handler listening on this channel. It is notified when void proxied services have exceptions thrown but still not when proxied services w/ a return value have endpoints throwing exceptions.



                      • #12
                        Well, the way that that Gateway works, it sets the 'errorChannel' header (just like it sets the 'replyChannel'). That way even if the downstream flow is asynchronous, it can still receive the Exception and make it appear no different than a blocking, synchronous call. That is really the main purpose of the Gateway proxy.

                        So, 2 questions:
                        1) does that make sense?
                        2) can you explain what you would expect/prefer?



                        • #13

                          1) does make sense.

                          Ideally, I could implement one strategy for handling errors per flow type. I see things as there being two types of flows, blocking and non-blocking with one of two directions, inbound or outbound. When a given customer's channel/flow requires asynchronous processing I want to use one errorHandling strategy whether or not the Gateway that starts the flow returns a value or not.

                          This way developers who implement a synchronous flow have one strategy/mechanism that can be used/re-used and the same for asynchronous flows. Right now, it looks like Gateway methods that return a value have to have endpoints and/or methods coded to do error handling in a way that looks more like synchronous flow methods.

                          Is this accurate, and does it make sense to you?


                          • #14
                            I'm considering a few options for this. Would a boolean flag on the <gateway> element that determines whether Exceptions should be thrown to the caller else intercepted and sent to the errorChannel work?

                            If so, the question is what to return to the caller?


                            • #15
                              1. I like the idea of the flag to notify the errorChannel if not make it a default.

                              2. That is the million dollar question. I need to think about this a bit more, as I am designing my retry feature.

                              Right now, I'd say that notifying the errorChannel and throwing the exception seem workable. Even better, it would be nice to define which exceptions get sent to the error channel, and which ones propogate back to the gateway.

                              When I think of the retry scenario I can see certain exceptions going to the error channel and one exception handler evaluating and routing/requeuing for retry. Once the retry threshold is exceeded, I throw another exception to indicate retry(ies) failed and let caller of the gateway handle that particular condition.

                              This could be something along the lines of the router component I came across that maps certain exceptions to a given channel, if I recall correctly.

                              What are your thoughts?