Commit 99c2fa69 authored by Nikolay Rybak's avatar Nikolay Rybak Committed by Stephane Nicoll

Handle AbstractReactiveHealthIndicator.doHealthCheck exception

Exceptions inside AbstractReactiveHealthIndicator.doHealthCheck()
method, outside of Mono pipeline, could fail whole endpoint
response instead of returning `DOWN` status from indicator.

See gh-10822
parent c50a0d85
...@@ -29,8 +29,17 @@ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthI ...@@ -29,8 +29,17 @@ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthI
@Override @Override
public final Mono<Health> health() { public final Mono<Health> health() {
return doHealthCheck(new Health.Builder()) try {
.onErrorResume((ex) -> Mono.just(new Health.Builder().down(ex).build())); return doHealthCheck(new Health.Builder())
.onErrorResume(this::handleFailure);
}
catch (Throwable ex) {
return handleFailure(ex);
}
}
private Mono<Health> handleFailure(Throwable ex) {
return Mono.just(new Health.Builder().down(ex).build());
} }
/** /**
......
...@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.redis; ...@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.redis;
import java.util.Properties; import java.util.Properties;
import io.lettuce.core.RedisConnectionException;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
...@@ -61,7 +62,7 @@ public class RedisReactiveHealthIndicatorTests { ...@@ -61,7 +62,7 @@ public class RedisReactiveHealthIndicatorTests {
} }
@Test @Test
public void redisIsDown() throws Exception { public void redisCommandIsDown() throws Exception {
ReactiveServerCommands commands = mock(ReactiveServerCommands.class); ReactiveServerCommands commands = mock(ReactiveServerCommands.class);
given(commands.info()).willReturn( given(commands.info()).willReturn(
Mono.error(new RedisConnectionFailureException("Connection failed"))); Mono.error(new RedisConnectionFailureException("Connection failed")));
...@@ -75,6 +76,18 @@ public class RedisReactiveHealthIndicatorTests { ...@@ -75,6 +76,18 @@ public class RedisReactiveHealthIndicatorTests {
verify(redisConnection).close(); verify(redisConnection).close();
} }
@Test
public void redisConnectionIsDown() throws Exception {
ReactiveRedisConnectionFactory redisConnectionFactory = mock(ReactiveRedisConnectionFactory.class);
given(redisConnectionFactory.getReactiveConnection()).willThrow(
new RedisConnectionException("Unable to connect to localhost:6379"));
RedisReactiveHealthIndicator healthIndicator = new RedisReactiveHealthIndicator(redisConnectionFactory);
Mono<Health> health = healthIndicator.health();
StepVerifier.create(health)
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
.verifyComplete();
}
private RedisReactiveHealthIndicator createHealthIndicator( private RedisReactiveHealthIndicator createHealthIndicator(
ReactiveRedisConnection redisConnection, ReactiveRedisConnection redisConnection,
ReactiveServerCommands serverCommands) { ReactiveServerCommands serverCommands) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment