# Failure handle does not seem to work with ElasticSearch

**URL:** <https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876>\
**Category:** Hibernate Search\
**Created:** [June 26, 2023, 4:39pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876 "2023-06-26T16:39:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Monkiki](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/monkiki/32/850_2.png) [@Monkiki](https://discourse.hibernate.org/u/Monkiki)\
**Post date:** [June 26, 2023, 4:39pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/1 "2023-06-26T16:39:24Z")

</div>

Hello all,

I’ve this line in my **application.properties** which should enable the custom failure handler but it does not seem to work:

```auto
spring.jpa.properties.hibernate.search.background_failure_handler=class:my.custom.config.HibernateSearchFailureHandler

```

I’m not able to get this custom failure handler working. In my test, Hibernate Search is configured to work with a ElasticSearch instance and when I shutdown the ElasticSearch instance I expect this failure handle to be called. Or maybe I’m wrong and won’t be called in this scenario. Can anyboy tell me?

This is the implementation which is based on the example found at reference documentation:

```auto
public class HibernateSearchFailureHandler implements FailureHandler {
	private static final Logger log = LoggerFactory.getLogger(HibernateSearchFailureHandler.class);

	@Override
	public void handle(FailureContext context) {
		String failingOperation = context.failingOperation().toString();
		Throwable throwable = context.throwable();
		log.error("FailureContext: {}", failingOperation, throwable);
	}

	@Override
	public void handle(EntityIndexingFailureContext context) {
		String failingOperation = context.failingOperation().toString();
		Throwable throwable = context.throwable();
		List<String> entities = new ArrayList<>();

		for (Object entityReference : context.entityReferences()) {
			entities.add(entityReference.toString());
		}

		log.error("EntityIndexingFailureContext: {} => {}", failingOperation, entities, throwable);
	}
}

```

BTW, in this documentation prepends the “class:” string and in other parts in the same documentation only put the full class with package. Are both the same thing or which one is the correct. In any caso none of them worked.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 26, 2023, 5:01pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/2 "2023-06-26T17:01:01Z")

</div>

Hello,

> [@Monkiki](#):
>
> I’m not able to get this custom failure handler working. In my test, Hibernate Search is configured to work with a ElasticSearch instance and when I shutdown the ElasticSearch instance I expect this failure handle to be called. Or maybe I’m wrong and won’t be called in this scenario. Can anyboy tell me?

I’d have to know which failing operation you are talking about exactly.

But in general, yes, the _background failure_ handler only gets called for failures happening in the _background_, i.e. for which you wouldn’t normally get an exception in the user thread.

If your goal is to ignore indexing errors, first I wouldn’t recommend that, as you would eventually end up with an out-of-sync index. This might not matter if you reindex every night, though.

Second, there are other options at your disposal:

- If you set the [automatic indexing synchronization strategy](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-indexing-automatic-synchronization) to `async`, indexing will become de facto a “background” operation and failures will get passed to the background failure handler.
- You may be able to configure a [custom automatic indexing strategy](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-indexing-automatic-synchronization-custom), which [involves in particular handling errors](https://github.com/hibernate/hibernate-search/blob/efed59d1901b978023f8b52559e86bd70ea97903/mapper/orm/src/main/java/org/hibernate/search/mapper/orm/automaticindexing/session/impl/AsyncAutomaticIndexingSynchronizationStrategy.java#L42-L59). In that case you may decide to skip the background failure handler completely.
- With the [`outbox-polling` coordination strategy](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#coordination-database-polling), you could push entity change events to a queue in the database, and have them processed in the background, so that your HTTP request processing threads are unaffected by Elasticsearch not being available. However, if it stays unavailable for a long time, events will pile up in the database and this might become a problem.
- Alternatively, I’ve seen people check whether Elasticsearch is up on Spring Boot’s startup, and generate some configuration dynamically to disable Hibernate Search if it’s not. This only works if you don’t expect Elasticsearch to become unavailable after startup, though.

As to ignoring search errors, you’ll have to catch exceptions and do it by hand. Using an abstraction layer or aspect-oriented programming might help.

> [@Monkiki](#):
>
> BTW, in this documentation prepends the “class:” string and in other parts in the same documentation only put the full class with package. Are both the same thing or which one is the correct. In any caso none of them worked.

They’re similar, but not always equivalent. See [Hibernate Search 6.2.2.Final: Reference Documentation](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#configuration-bean-reference-parsing)

---

<div class="post-metadata">

**Author:** ![Monkiki](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/monkiki/32/850_2.png) [@Monkiki](https://discourse.hibernate.org/u/Monkiki)\
**Post date:** [June 27, 2023, 12:02pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/3 "2023-06-27T12:02:39Z")

</div>

The problem was that I didn’t change the automatic indexing synchronization strategy to async.

BTW, I’m not sure if I understood, but chossing **async** will just keep the queue of items to be processed in memory and to avoid memory issues I should use the **outbox-polling coordinator strategy**?

Thanks for the quick response!

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 27, 2023, 12:05pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/4 "2023-06-27T12:05:11Z")

</div>

> [@Monkiki](#):
>
> chossing **async** will just keep the queue of items to be processed in memory

Yes, though the queue is there whatever happens. `async` mostly means your HTTP request thread will go on without checking whether indexing succeeded, it’ll just let that run in the background.

> [@Monkiki](#):
>
> to avoid memory issues I should use the **outbox-polling coordinator strategy**?

To some extent yes, but that’s not the main point. See [Hibernate Search 6.2.2.Final: Reference Documentation](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#architecture-examples-outbox-polling-elasticsearch-pros-and-cons)

---

<div class="post-metadata">

**Author:** ![Monkiki](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/monkiki/32/850_2.png) [@Monkiki](https://discourse.hibernate.org/u/Monkiki)\
**Post date:** [June 27, 2023, 12:10pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/5 "2023-06-27T12:10:34Z")

</div>

> [@yrodiere](#):
>
> Yes, though the queue is there whatever happens. `async` mostly means your HTTP request thread will go on without checking whether indexing succeeded, it’ll just let that run in the background.

Ok, but this would only happen with ElasticSearch. In case of Lucene backend I’ve had OutOfMemory problems under heavy load. I suppose Lucene (or the computer disk) were not fast enought to process all these requests.

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 27, 2023, 12:14pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/6 "2023-06-27T12:14:25Z")

</div>

> [@Monkiki](#):
>
> Ok, but this would only happen with ElasticSearch

No, same thing with Lucene.

> [@Monkiki](#):
>
> In case of Lucene backend I’ve had OutOfMemory problems under heavy load

I’d expect such errors to come from entity processing (i.e. when going through the entity graph to extract all the information to index), and that would happen for both Lucene and Elasticsearch. In any case, yes, `outbox-polling` coordination could help with this since you would be able to scale HTTP processing independently from indexing, e.g. have 100 HTTP request processing threads and only 1-2 indexing threads. See [Hibernate Search 6.2.2.Final: Reference Documentation](https://docs.jboss.org/hibernate/search/6.2/reference/en-US/html_single/#coordination-outbox-polling-event-processor-sharding)

I could be more useful with a reproducer, but I understand that’s hard.

---

<div class="post-metadata">

**Author:** ![Monkiki](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/monkiki/32/850_2.png) [@Monkiki](https://discourse.hibernate.org/u/Monkiki)\
**Post date:** [June 27, 2023, 2:30pm UTC](https://discourse.hibernate.org/t/failure-handle-does-not-seem-to-work-with-elasticsearch/7876/7 "2023-06-27T14:30:13Z")

</div>

Ok, thanks for this valuable info.
