[ 
https://issues.apache.org/jira/browse/CAMEL-26452?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-26452:
--------------------------------
    Fix Version/s: 4.24.0

> camel-beanio - BeanIOSplitter drops the record after each invalid record that 
> the error handler replaces with a result
> ----------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26452
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26452
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-beanio
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> A custom {{BeanIOErrorHandler}} can turn an invalid record into a result with 
> {{handleErrorAndAddAsResult(Object)}} (the {{MyErrorHandler}} of the 
> component tests does it). The {{beanio}} data format adds that result to its 
> list; {{BeanIOSplitter}} gives it to its {{BeanIOIterator}} with 
> {{setNext(result)}}.
> The error handler is called from inside {{BeanReader.read()}}. After the 
> handler returns, BeanIO goes on reading and {{read()}} returns the next valid 
> record. {{BeanIOIterator.next()}} then does:
> {code:java}
> next = reader.read();        // the valid record after the invalid one
> if (forceNext != null) {
>     next = forceNext;        // ... is replaced by the result of the error 
> handler
>     forceNext = null;
> }
> {code}
> So the valid record that follows a handled invalid record is lost, and of two 
> invalid records in a row only the last result is kept (the single 
> {{forceNext}} field is overwritten). Nothing is logged. Only a single invalid 
> record at the end of the data (where {{read()}} returns null) works, which is 
> what {{BeanIOSplitterCustomBeanReaderErrorHandlerTest.testSplitFail}} covers.
> Reproducer (the employee mapping of the component tests, 
> {{split(splitter).streaming()}} with 
> {{setBeanReaderErrorHandlerType(MyErrorHandler.class)}}):
> ||Records||split on main (4ab42b192b26)||unmarshal with the data format||
> |Joe, Jane (invalid salary), Jon|Joe, ErrorDto|Joe, ErrorDto, Jon|
> |Joe, Jane (invalid), Jim (invalid), Jon, Jack|Joe, ErrorDto, Jack|Joe, 
> ErrorDto, ErrorDto, Jon, Jack|
> A route that splits data with such an error handler silently drops a valid 
> record after each invalid one, with any BeanIO stream format. The same code 
> is on the 4.14.x, 4.18.x and 4.22.x branches.
> *Proposal*
> * {{BeanIOIterator}} keeps the results that the error handler adds during a 
> read in a queue, and returns them in their order before the record that the 
> read returned (the same order as the data format's list). {{setNext}} adds to 
> the queue.
> * Tests: an invalid record in the middle, two invalid records in a row 
> followed by valid ones (with their order), an invalid first record, and an 
> error handler type that cannot be created.
> Next to it: the first record is read in the {{BeanIOIterator}} constructor, 
> before {{BeanIOSplitter}} sets the error handler on the reader, so an invalid 
> first record fails the split even with {{ignoreInvalidRecords=true}} or a 
> custom error handler; and when the error handler cannot be created (a wrong 
> {{beanReaderErrorHandlerType}}), the reader of the body is not closed. 
> Proposal: set the error handler before the first read, inside the block that 
> closes the reader on a failure.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to