I am writing a client implementation for a binary protocol using a ProtocolCodecFilter with a DemuxingProtocolCodecFactory and a list of MessageDecoder's in the same way as the MINA SumUp example.
I also use a DemuxingIoHandler to handle responses and exceptions and I am in general very pleased with how this works.
But if an Exception is thrown from the decode()-method the problem begins.
The Exception is passed on to an ExceptionHandler just as excpected but the DemuxingProtocolDecoder's state.currentDecoder is not cleared so a subsequent decode operation is passed directly to the previously used MessageDecoder's decode()-method without selecting a new decoder, using decodable()-calls. This is of course a problem as the next message could require a different decoder and chances are big that the decoding will throw a new Exception and we can't recover from that state.
This differs from what happens if you return MessageDecoderResult.NOT_OK from decode() (where the state.currentDecoder is cleared) even though both events are documented as "protocol specification violations".
In conjunction with this the IoBuffer can be "half read" when the Exception is thrown and must some how be cleared before new messages can be received and decoded.
One approach to go around this is to do a try-catch in every decode()-method and skip the remaining bytes in the buffer and return NOT_OK in the catch-block.
Sadly enough you can not BOTH return NOT_OK and re-throw the Exception. So the nice ExceptionHandler-functionality in MINA goes to waste.
Also it feels wrong to be forced to do try-catch in every decode()-method for Exceptions that make the current message unreadable, could not the framework handle that and give subsequent messages a chance to be properly decoded?
(Exceptions during decoding that you ARE prepared for and CAN handle to rescue the current message is a different story, the specific decode()-method can catch those and handle them in a proper way.)
My humble suggestion is to let the DemuxingProtocolDecoder in it's doDecode() catch Exceptions, reset the current decoder and buffer and re-throw the Exceptions. But I'm no expert of MINA internals.
I am made aware that the IoBuffer can contain more than one message and that clearing it could loose a valid second message.
But if the decode()-method chooses not to handle the Exception, my guess is that there is no way of knowing where the first message ends and the second begins outside that MessageDecoder anyway.