In web services world, faults are not exceptions, but usually an xml
payload.  In the java world, faults would be like checked exceptions
and errors runtime exceptions.  However, distinguishing a fault from
an out message by (instanceof Exception) is imho not sufficient

On Thu, Jul 9, 2009 at 07:35, Hadrian Zbarcea<hzbar...@gmail.com> wrote:
> Hi,
>
> Comments inline.
>
> Hadrian
>
> On Jul 9, 2009, at 12:54 AM, Claus Ibsen wrote:
>
>> On Wed, Jul 8, 2009 at 9:52 PM, Hadrian Zbarcea<hzbar...@gmail.com> wrote:
>>>
>>> Hi,
>>>
>>> As we approach the 2.0, there is one more hanging issue I would like
>>> addressed, if possible.  It's the thorny issue of Faults and Exceptions
>>> that
>>> started in
>>> http://issues.apache.org/activemq/browse/CAMEL-316 (see also the related
>>> nabble thread linked in the issue description).
>>>
>>> I am less concerned about how the DefaultExchange is implemented and I
>>> hope
>>> to reach an agreement on what the Exchange api should be (please find the
>>> list of Exchange methods below).
>>>
>>> As far as faults/exceptions are concerned, Roman thinks that the whole
>>> concept of in/out/fault/exception is artificial, and only one payload
>>> (message) api should be enough (Roman please correct me if I misinterpret
>>> your position).  My opinion is that we *must* distinguish between
>>> persistent
>>> (fault) and transient (exception) errors for the simple reason that they
>>> have different semantics.  As Roman correctly points out, faults are more
>>> like outputs, have more of application level semantics and are normally
>>> handled by the client, where exceptions (transient errors) are something
>>> camel could try to recover from, without much knowledge about the
>>> application.  I think that the presence of fault in the camel api is not
>>> due
>>> to it being explicitly modeled by jbi and wsdl, as Roman suggests, and
>>> Camel
>>> simply copying that, but it's modeled in Camel for the same reason it's
>>> modeled in jbi and wsdl, to differentiate transient from persistent
>>> errors
>>> in a non ambiguous way.
>>
>> I am one of the persons that would love the Camel Exchange / Message
>> API to be a bit simpler. It has a fair shares of methods.
>>
>> Having listening and discussing with Hadrian on this and doing my own
>> investigations and whatnot I do belive that Hadrian is absolutely
>> right when it comes to FAULT. It has a good place in the API.  I am +1
>> on having FAULT as we do now.
>>
>> The grief I have left is that the IN and OUT. It makes sense to have
>> them and they provide a good value. However they have a big drawnback
>> in how they are routed in Camel with the Pipeline processor, that
>> mimics the pipes and filters EIP. And as a result the OUT will be used
>> as IN
>> in the next step in the route. So its not like you can steadily build
>> up an OUT message on-the-fly during many steps in the route path.
>>
>> Example
>> from("direct:start").process(new Processor()).to("log:foo");
>>
>> a) From
>> IN = Hello World
>> OUT = null
>>
>> b) Processor
>> IN Hello World
>> OUT = Bye World
>>
>> c) Log
>> IN = Bye World
>> OUT = null
>>
> Yes, from an external observer's perspective, this is precisely what
> happens.  How we decide to store it, how many fields we need, is an
> implementation detail of the DefaultExchange.  I don't think the copy from
> out/in is too expensive, but I would be ok with having only one field to
> store the current message in DefaultExchange (I assume that's what you
> propose).  However, my question is about what the api should be.
>
>
>>
>> And then the getOut() method that lazy creates a new empty OUT message
>> is also a pita, as it can lead to people loosing their messages if
>> they do some System out logging of their own
>>
>> public void process(Exchange e) {
>>  System.out.println(exchange.getIn());
>>  System.out.println(exchange.getOut());
>>  // boom you lost your message when its routed to next node in route
>> path, as getOut() created a new empty OUT message that will by used in
>> the pipes and filters EIP routed with the Pipeline
>> }
>>
>> We had this IN OUT discussion a while back and at that time we ended
>> up with a compromise of having a hasOut() method so you should do, to
>> be safe:
>>  System.out.println(exchange.getIn());
>>  if (exchange.hasOut()) {
>>      System.out.println(exchange.getOut());
>>  }
>>
>> Still a pita with the lazy creation IMHO.
>
> The lazyCreate methods are actually deprecated, and imho should be removed
> now.  This would eliminate the confusion.
>
>
>>>
>>> If we were to go with only get/setMessage() api, we would still need
>>> methods
>>> (or some ways) to distinguish between the kind of message we are dealing
>>> with (in/out/fault/exception) so we'd only move the problem somewhere
>>> else.
>>>
>>> So the question becomes if we leave the api the way it is, or we replace
>>> the
>>> get/setFault apis with get/setOut, in which case we'll need something
>>> like:
>>>   boolean isFault();
>>> method in the Message api or keep the hasFault() method on the Exchange.
>>
>> Good question
>>
>> If you use OUT instead then we need to add a isFault() on the
>> org.apache.camel.Message API that
>> the IN message also implements.
>>
>> It could make sense to use OUT as well for FAULT.
>> But how should the API look like to set an OUT as Fault?
>>
>> Something a like this?
>>
>> getOut().setBody("Unknown bank account number.");
>> getOut().setFault(true);
>
> Not quite, I had something like this in mind (there is no setFault()
> method):
> getOut().setBody(java-lang-Exception-derivedObject);
>
> boolean isFault() {
>    return getBody() instanceof Exception;
> }
>
> Personally I am ok with the limitation not being able to have an out of a
> java.lang.Exception type (that would then be a Fault).  I can't imagine a
> case where an Exception would be an expected out, and in such cases one
> could always serialize or wrap it.  The fact that the Fault would be an
> Exception type would be a camel convention that needs to be followed by all
> components.
>
> Another option would be add  header HAS_FAULT or something like that, in
> which case both the out and the fault could be of any type.
>
>
>>
>>>
>>> Thoughts?
>>>
>>>
>>>   ExchangePattern getPattern();
>>>   void setPattern(ExchangePattern pattern);
>>>
>>>   Object getProperty(String name);
>>>   <T> T getProperty(String name, Class<T> type);
>>>   void setProperty(String name, Object value);
>>>   Object removeProperty(String name);
>>>   Map<String, Object> getProperties();
>>>
>>>   Message getIn();
>>>   void setIn(Message in);
>>>
>>>   Message getOut();
>>>   boolean hasOut();
>>>   Message getOut(boolean lazyCreate);
>>>   void setOut(Message out);
>>>
>>>   Message getFault();
>>>   boolean hasFault();
>>>   Message getFault(boolean lazyCreate);
>>>   void removeFault();
>>> // removeFault() is only used in one place
>>
>> +1 to remove it. You can just do setFault(null) instead. I will fix it
>> asap.
>>
>>
>>
>>>
>>>   Exception getException();
>>>   <T> T getException(Class<T> type);
>>>   void setException(Exception e);
>>>   boolean isFailed();
>>>
>>>   boolean isTransacted();
>>>   boolean isRollbackOnly();
>>>
>>>   CamelContext getContext();
>>>
>>>   Exchange newInstance();
>>>   Exchange copy();
>>>   Exchange newCopy(boolean handoverOnCompletion);
>>>   void copyFrom(Exchange source);
>>>
>>>   Endpoint getFromEndpoint();
>>>   void setFromEndpoint(Endpoint fromEndpoint);
>>>
>>>   UnitOfWork getUnitOfWork();
>>>   void setUnitOfWork(UnitOfWork unitOfWork);
>>>
>>>   String getExchangeId();
>>>   void setExchangeId(String id);
>>>
>>>   void addOnCompletion(Synchronization onCompletion);
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> Claus Ibsen
>> Apache Camel Committer
>>
>> Open Source Integration: http://fusesource.com
>> Blog: http://davsclaus.blogspot.com/
>> Twitter: http://twitter.com/davsclaus
>
>



-- 
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com

Reply via email to