This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-26516-web3j-filter-cancel in repository https://gitbox.apache.org/repos/asf/camel.git
commit a981e899e2f56dd782556bdf9de6ce520728ed2c Author: Claus Ibsen <[email protected]> AuthorDate: Tue Nov 3 17:36:17 2026 +0100 CAMEL-26516: camel-web3j - document the UndeliverableException when web3j fails to uninstall a filter When a filter-based consumer stops, or web3j drops the filter after a failed block or transaction fetch, web3j calls eth_uninstallFilter. If that fails, RxJava reports an UndeliverableException caused by web3j's FilterException. It is only noise and the cause is in web3j (LFDT-web3j/web3j#1937), so Camel does not change. The component doc now explains it and shows an RxJavaPlugins error handler that logs it at a lower level. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../apache/camel/catalog/docs/web3j-component.adoc | 36 ++++++++++++++++++++++ .../camel-web3j/src/main/docs/web3j-component.adoc | 36 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/web3j-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/web3j-component.adoc index fd1ebba1d52d..e2a7e50c1a44 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/web3j-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/web3j-component.adoc @@ -171,3 +171,39 @@ YAML:: atBlock: 10 ---- ==== + +== UndeliverableException when a filter is removed + +The consumer operations `ETH_LOG_OBSERVABLE`, `ETH_BLOCK_HASH_OBSERVABLE`, `ETH_PENDING_TRANSACTION_HASH_OBSERVABLE`, +`BLOCK_OBSERVABLE`, `TRANSACTION_OBSERVABLE` and `PENDING_TRANSACTION_OBSERVABLE` install a filter on the node and poll it. +web3j removes the filter with `eth_uninstallFilter` when the consumer stops. For `BLOCK_OBSERVABLE`, +`TRANSACTION_OBSERVABLE` and `PENDING_TRANSACTION_OBSERVABLE`, web3j also removes it when fetching a block or a +transaction fails, before the consumer subscribes again. + +If `eth_uninstallFilter` fails, for example because the node is down or has already dropped the filter, RxJava reports an +`io.reactivex.exceptions.UndeliverableException` caused by web3j's `org.web3j.protocol.core.filters.FilterException`. +By default RxJava prints the stack trace and passes it to the uncaught exception handler of the thread. +This is only noise: the consumer keeps working. The cause is in web3j, see +https://github.com/LFDT-web3j/web3j/issues/1937[web3j issue 1937]. + +To log these errors at a lower level, an application can set a JVM-wide RxJava 2 error handler once at startup, +before the routes start. The handler below logs the web3j filter errors at DEBUG and handles all other errors as RxJava +does by default: + +[source,java] +---- +import io.reactivex.exceptions.UndeliverableException; +import io.reactivex.plugins.RxJavaPlugins; +import org.web3j.protocol.core.filters.FilterException; + +RxJavaPlugins.setErrorHandler(e -> { + if (e instanceof UndeliverableException && e.getCause() instanceof FilterException) { + LOG.debug("web3j could not uninstall a filter: {}", e.getCause().getMessage()); + return; + } + // what RxJava does when no error handler is set + e.printStackTrace(); + Thread thread = Thread.currentThread(); + thread.getUncaughtExceptionHandler().uncaughtException(thread, e); +}); +---- diff --git a/components/camel-web3j/src/main/docs/web3j-component.adoc b/components/camel-web3j/src/main/docs/web3j-component.adoc index fd1ebba1d52d..e2a7e50c1a44 100644 --- a/components/camel-web3j/src/main/docs/web3j-component.adoc +++ b/components/camel-web3j/src/main/docs/web3j-component.adoc @@ -171,3 +171,39 @@ YAML:: atBlock: 10 ---- ==== + +== UndeliverableException when a filter is removed + +The consumer operations `ETH_LOG_OBSERVABLE`, `ETH_BLOCK_HASH_OBSERVABLE`, `ETH_PENDING_TRANSACTION_HASH_OBSERVABLE`, +`BLOCK_OBSERVABLE`, `TRANSACTION_OBSERVABLE` and `PENDING_TRANSACTION_OBSERVABLE` install a filter on the node and poll it. +web3j removes the filter with `eth_uninstallFilter` when the consumer stops. For `BLOCK_OBSERVABLE`, +`TRANSACTION_OBSERVABLE` and `PENDING_TRANSACTION_OBSERVABLE`, web3j also removes it when fetching a block or a +transaction fails, before the consumer subscribes again. + +If `eth_uninstallFilter` fails, for example because the node is down or has already dropped the filter, RxJava reports an +`io.reactivex.exceptions.UndeliverableException` caused by web3j's `org.web3j.protocol.core.filters.FilterException`. +By default RxJava prints the stack trace and passes it to the uncaught exception handler of the thread. +This is only noise: the consumer keeps working. The cause is in web3j, see +https://github.com/LFDT-web3j/web3j/issues/1937[web3j issue 1937]. + +To log these errors at a lower level, an application can set a JVM-wide RxJava 2 error handler once at startup, +before the routes start. The handler below logs the web3j filter errors at DEBUG and handles all other errors as RxJava +does by default: + +[source,java] +---- +import io.reactivex.exceptions.UndeliverableException; +import io.reactivex.plugins.RxJavaPlugins; +import org.web3j.protocol.core.filters.FilterException; + +RxJavaPlugins.setErrorHandler(e -> { + if (e instanceof UndeliverableException && e.getCause() instanceof FilterException) { + LOG.debug("web3j could not uninstall a filter: {}", e.getCause().getMessage()); + return; + } + // what RxJava does when no error handler is set + e.printStackTrace(); + Thread thread = Thread.currentThread(); + thread.getUncaughtExceptionHandler().uncaughtException(thread, e); +}); +----
