diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index afd67b885..e3ae6c508 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -38,6 +38,7 @@ import reactor.util.context.Context; import org.springframework.beans.factory.BeanFactory; import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.method.HandlerMethod; @@ -422,9 +423,11 @@ public final class TraceWebFilter implements WebFilter, Ordered { @Override public int statusCode() { - if (this.throwable != null - && this.throwable instanceof ResponseStatusException) { - return ((ResponseStatusException) this.throwable).getStatus().value(); + if (!this.delegate.isCommitted() && this.throwable != null) { + if (this.throwable instanceof ResponseStatusException) { + return ((ResponseStatusException) this.throwable).getStatus().value(); + } + return HttpStatus.INTERNAL_SERVER_ERROR.value(); } return delegate.getStatusCode() != null ? delegate.getStatusCode().value() : 0; diff --git a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java index aeb0c6be1..9c42d5d68 100644 --- a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java @@ -88,6 +88,12 @@ public class TraceWebFluxTests { thenSpanWith404StatusCodeWasReported(spans, response); spans.clear(); + // when + response = whenRequestIsSent(port, "/exception"); + // then + thenSpanWithExceptionWasReported(spans, response); + spans.clear(); + // when ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port); // then @@ -151,6 +157,15 @@ public class TraceWebFluxTests { value -> then(value).isEqualTo("404")); } + private void thenSpanWithExceptionWasReported(TestSpanHandler spans, + ClientResponse response) { + Awaitility.await() + .untilAsserted(() -> then(response.statusCode().value()).isEqualTo(500)); + then(spans).hasSize(1); + then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", + value -> then(value).isEqualTo("500")); + } + private void thenNoSpanWasReported(TestSpanHandler spans, ClientResponse response, Controller2 controller2) { Awaitility.await().untilAsserted(() -> { @@ -252,6 +267,11 @@ public class TraceWebFluxTests { return Flux.just(sampled.toString()); } + @GetMapping("/exception") + public Flux exception() { + throw new RuntimeException("Exception"); + } + } }