[ 
https://issues.apache.org/jira/browse/CAMEL-26516?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18137288#comment-18137288
 ] 

Claus Ibsen commented on CAMEL-26516:
-------------------------------------

Analysis before a fix. No code change yet: every fix is a design choice, so I 
need a decision first.

*Confirmed.* A scratch test that runs the real web3j 6.1.0 code against a 
mocked {{Web3jService}} (no node) reproduces it. The test subscribes 
{{ethBlockHashFlowable()}}, makes {{eth_uninstallFilter}} fail with an 
{{IOException}} and disposes the subscription. {{RxJavaPlugins.onError}} then 
gets {{UndeliverableException}} caused by {{FilterException: Error sending 
request}}.

*When it happens:*
* when a route stops while the node is down, or after the node has already 
dropped the filter (Geth drops a filter that has not been polled for 5 
minutes). In that case {{isUninstalled}} is false and web3j throws "Filter with 
id ... failed to uninstall";
* also outside of a stop. {{blockFlowable}}, {{transactionFlowable}} and 
{{pendingTransactionFlowable}} cancel their filter when an inner 
{{eth_getBlockByHash}} or {{eth_getTransactionByHash}} call fails. That is the 
error the consumer resubscribes on since CAMEL-25730. If the node is down, the 
uninstall fails too, so the stack trace also shows at the first error of an 
outage.

*Effect:* only noise. RxJava prints the stack trace on stderr and passes it to 
the uncaught exception handler of the current thread. The thread keeps running, 
and the consumer stops or resubscribes normally.

*Why Camel cannot catch it:* {{JsonRpc2_0Rx.run}} sets {{filter::cancel}} as 
the {{Cancellable}} of a {{Flowable.create}}. RxJava's 
{{CancellableDisposable}} sends any exception from it to 
{{RxJavaPlugins.onError}}, and {{dispose()}} never throws. {{JsonRpc2_0Web3j}} 
keeps the polling interval and the executor in private fields. So Camel cannot 
rebuild the filter Flowables for a user-supplied {{web3j}} bean without losing 
its settings.

*Upstream:* web3j main has the same {{Filter.cancel()}}. The open issue 
LFDT-web3j/web3j#1937 ("Filter with id ... failed to uninstall", 2023) has had 
no fix.

*Options:*
# Change nothing in Camel. Propose upstream (on #1937) that {{Filter.cancel()}} 
logs instead of throwing, or that {{JsonRpc2_0Rx}} catches it. Add a short tip 
to the web3j component doc: an application can set 
{{RxJavaPlugins.setErrorHandler}}.
# camel-web3j installs an RxJava 2 error handler when none is set and RxJava is 
not locked down. The handler logs an {{UndeliverableException}} caused by a 
{{FilterException}} at WARN and passes everything else to RxJava's default 
handling. The component removes the handler on stop if it is still the one it 
installed. Downside: this is JVM-wide state set by a component, so other RxJava 
2 users and a second CamelContext share it.
# Camel builds the three filter Flowables itself from web3j's public 
{{BlockFilter}}, {{PendingTransactionFilter}} and {{LogFilter}}, and catches 
{{FilterException}} on cancel. Downside: this needs a new pollingInterval 
option and its own executor, and the polling interval of a user-supplied 
{{web3j}} bean would be ignored.

*Recommendation:* option 1. The bug is in web3j, it is only noise, and options 
2 and 3 have side effects that are worse.

*Question:* which option? With option 1, should I add the doc tip and a comment 
with the root cause on #1937?

_Claude Code on behalf of Claus Ibsen (davsclaus)_


> camel-web3j - stopping a filter consumer reports an UndeliverableException 
> when eth_uninstallFilter fails
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26516
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26516
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-web3j
>            Reporter: Claus Ibsen
>            Priority: Minor
>             Fix For: 4.24.0
>
>
> Found while fixing CAMEL-26173 (bug 4 of that issue, not fixed there). When a 
> consumer using a web3j filter (block, transaction or log observable) stops 
> and the node fails {{eth_uninstallFilter}}, web3j's {{Filter.cancel()}} 
> throws a {{FilterException}}. RxJava 2's {{CancellableDisposable}} hands it 
> to {{RxJavaPlugins.onError}}, which reports an {{UndeliverableException}} 
> (printed on stderr / to the global handler). {{dispose()}} itself does not 
> throw, so Camel cannot catch it.
> Options:
> * ask web3j to log instead of throw in {{Filter.cancel()}} (preferred);
> * install a JVM-wide RxJava error handler from camel-web3j when none is set 
> (global side effect);
> * implement the filter Flowables in Camel.
> Recommendation: report it upstream to web3j and link the upstream issue here.
> _Claude Code on behalf of Claus Ibsen (davsclaus)_



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

Reply via email to