5 Replies Latest reply on May 23, 2014 4:42 PM by mimer

    Handling errors from Java Validator in REST binding

    mimer

      Hi

       

      I was wondering what the best practice for for handling errors from custom JavaValidators is? If a validation fails, and i haven't written a custom MessageComposer, it gets to the client as a HTTP 500, which obviously isn't what i want, but do i have to do all the error message handling myself? Unfortunately the documentation and quickstarts aren't much help, and looking at the Message Trace , it looks like i have to dig everything out of a CamelExceptionCaught.

       

      What would be the correct way to handle validation errors?

       

      ------- Begin Message Trace -------

      Consumer -> {urn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0}InventoryBalanceService

      Provider -> {urn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0}InventoryBalanceService

      Operation -> getInventoryBalance

      MEP -> IN_OUT

      Phase -> OUT

      State -> FAULT

      Exchange Context ->

          CamelCreatedTimestamp ............................: Wed May 07 11:03:16 CEST 2014

          CamelExceptionCaught .............................: org.switchyard.HandlerException: SWITCHYARD014000: Validator 'org.switchyard.validate.internal.ValidatorUtil$1' failed: ItemSKUGroup is not defined [null].

          CamelFailureEndpoint .............................: direct://%7Burn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0%7DInventoryBalanceService

          CamelFailureHandled ..............................: true

          CamelFilterMatched ...............................: true

          CamelToEndpoint ..................................: direct://%7Burn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0%7DInventoryBalanceService

          org.switchyard.bus.camel.consumer ................: ServiceReference [name={urn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0}InventoryBalanceService, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: isAlive : IN_OUT  : [null, java:java.lang.String, null], SWITCHYARD010008: getInventoryBalance : IN_OUT  : [java:com.dtgroup.services.inventory.InventoryBalanceRequest, java:com.dtgroup.services.inventory.InventoryBalanceListResponse, null]]], domain=ServiceDomain [name=null]]

          org.switchyard.bus.camel.contract ................: org.switchyard.metadata.BaseExchangeContract@12488bd

          org.switchyard.bus.camel.dispatcher ..............: org.switchyard.bus.camel.ExchangeDispatcher@18d3e36

          org.switchyard.bus.camel.fault ...................: true

          org.switchyard.bus.camel.labels ..................: {org.switchyard.exchangeGatewayName=[org.switchyard.label.behavior.transient], org.switchyard.exchangeInitiatedNS=[org.switchyard.label.behavior.transient], org.switchyard.security.context.SecurityContext=[org.switchyard.label.behavior.transient], org.switchyard.exchange.transaction.beforeInvoked=[org.switchyard.label.behavior.transient]}

          org.switchyard.bus.camel.phase ...................: OUT

          org.switchyard.bus.camel.provider ................: Service [name={urn:com.dtgroup.mobilebranch.switchyard:MobileBranchSwitchyardServices:1.0}InventoryBalanceService, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: getInventoryBalance : IN_OUT  : [java:com.dtgroup.services.inventory.InventoryBalanceRequest, java:com.dtgroup.services.inventory.InventoryBalanceListResponse, null], SWITCHYARD010008: isAlive : IN_OUT  : [null, java:java.lang.String, null]]], domain=ServiceDomain [name=null], metadata=org.switchyard.metadata.ServiceMetadataBuilder$ServiceMetadataImpl@1e98cd2]

          org.switchyard.bus.camel.replyHandler ............: org.switchyard.component.common.SynchronousInOutHandler@1ef8a98

          org.switchyard.exchange.transaction.beforeInvoked : true

          org.switchyard.exchangeGatewayName ...............: InventoryBalanceRestService

          org.switchyard.exchangeInitiatedNS ...............: 1399453396740738000

          org.switchyard.rollbackOnFault ...................: true

      Message Context ->

          org.switchyard.bus.camel.labels .....: {org.switchyard.bus.camel.messageSent=[org.switchyard.label.behavior.transient], org.switchyard.exchangeDurationMS=[org.switchyard.label.behavior.transient]}

          org.switchyard.bus.camel.messageSent : true

          org.switchyard.exchangeDurationMS ...: 42

          org.switchyard.messageId ............: ID-McDennis-local-51041-1399452748164-5-3

          org.switchyard.relatesTo ............: ID-McDennis-local-51041-1399452748164-5-1

      ------ End Message Trace -------

       

      Thanks!

      /Dennis

        • 1. Re: Handling errors from Java Validator in REST binding
          kcbabo

          Can you attach an example app to reproduce this behavior?  With RESTEasy bindings, you need to return a JAX-RS Response type to get fine-grained control over the response code and message.  I'm guessing that this is just resulting in a WebApplicationException today, which would default to 500.

          • 2. Re: Re: Handling errors from Java Validator in REST binding
            mimer

            Hi Keith

             

            I've modified an existing example, to include a validator - you will get a validation error, if you call the following REST URL: /StockQuote/stocks/quote/FISH/AAPL

             

            You are probably right about your point about the WebApplicationException, but i'm looking for a "best practice" approach to handling the error.

             

            ... And i apologize in advance for the stupid example, but it was fairly easy to create ;-)

             

            Thanks!

            /Dennis

            • 3. Re: Re: Re: Handling errors from Java Validator in REST binding
              kcbabo

              The default RESTEasyMessageComposer will throw a WebApplicationException whenever the exchange is a fault.  Since you already have a custom composer in your example application, then you can just detour around that with logic like this:

               

                      // snipped
                      else {
                          System.out.println("Content: "+content);
                      }
                      
                      if (exchange.getState() != ExchangeState.FAULT) {
                          super.decompose(exchange, target);
                      } else {
                          target.setParameters(new Object[] {exchange.getMessage().getContent(String.class)});
                      }
              
                      return target;
              

               

              Which results in a reply like this:

               

              org.switchyard.HandlerException: SWITCHYARD014000: Validator 'org.switchyard.validate.internal.ValidatorUtil$1' failed: Please don't ask for fish stock!StockQuote
              

               

              It's sort of lame that our localized error string wraps the custom validation error.  Only thing I can say there is parse it out on your own if it's a problem for now and please file a JIRA if you would prefer to see the custom validation result message appear alone.

              • 4. Re: Re: Re: Re: Handling errors from Java Validator in REST binding
                kcbabo

                I should mention that the reply above is the HTTP reply, as in:

                 

                > GET /StockQuote/stocks/quote/FISH/AAPL HTTP/1.1
                > Host: localhost:8080
                > Accept: */*
                >
                < HTTP/1.1 200 OK
                < Server: Apache-Coyote/1.1
                < Content-Type: application/json
                < Content-Length: 152
                < Date: Tue, 20 May 2014 15:06:34 GMT
                <
                
                org.switchyard.HandlerException: SWITCHYARD014000: Validator 'org.switchyard.validate.internal.ValidatorUtil$1' failed: Please don't ask for fish stock!
                
                • 5. Re: Re: Re: Re: Handling errors from Java Validator in REST binding
                  mimer

                  Hi Keith

                   

                  Thanks for your answer - it wasn't exactly what we were hoping the answer would be, but we'll just have to do some coding in the composer then. It would've been nice, if where was a way of signaling what the error was via a validation- or errorcode or something, but we'll manage with the string.

                   

                  Thanks!

                  Dennis