[
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)