diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index 05aceb2f9..a3b0987a1 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -88,29 +88,33 @@ public abstract class ReactorSleuth { if (!springContext.isActive()) { if (log.isTraceEnabled()) { String message = "Spring Context [" + springContext - + "] is not yet refreshed. This is unexpected. Reactor Context is [" + sub.currentContext() + + "] is not yet refreshed. This is unexpected. Reactor Context is [" + context(sub) + "] and name is [" + name(sub) + "]"; log.trace(message); } return sub; } + Context context = context(sub); + + if (log.isTraceEnabled()) { + log.trace("Spring context [" + springContext + "], Reactor context [" + context + "], name [" + + name(sub) + "]"); + } + // Try to get the current trace context bean, lenient when there are problems CurrentTraceContext currentTraceContext = lazyCurrentTraceContext.get(); if (currentTraceContext == null) { - boolean assertOn = false; - assert assertOn = true; // gives a message in unit test failures - if (log.isTraceEnabled() || assertOn) { + if (log.isTraceEnabled()) { String message = "Spring Context [" + springContext - + "] did not return a CurrentTraceContext. Reactor Context is [" + sub.currentContext() + + "] did not return a CurrentTraceContext. Reactor Context is [" + context + "] and name is [" + name(sub) + "]"; log.trace(message); - assert false : message; // should never happen, but don't break. } return sub; } - Context context = contextWithBeans(springContext, sub); + context = contextWithBeans(context, springContext, sub); if (log.isTraceEnabled()) { log.trace("Spring context [" + springContext + "], Reactor context [" + context + "], name [" + name(sub) + "]"); @@ -132,9 +136,8 @@ public abstract class ReactorSleuth { }); } - private static Context contextWithBeans(ConfigurableApplicationContext springContext, + private static Context contextWithBeans(Context context, ConfigurableApplicationContext springContext, CoreSubscriber sub) { - Context context = sub.currentContext(); if (!context.hasKey(Tracer.class)) { context = context.put(Tracer.class, springContext.getBean(Tracer.class)); } @@ -164,11 +167,23 @@ public abstract class ReactorSleuth { if (!springContext.isActive()) { return sub; } - final Context context = contextWithBeans(springContext, sub); + final Context context = contextWithBeans(context(sub), springContext, sub); return new SleuthContextOperator<>(context, sub); }); } + private static Context context(CoreSubscriber sub) { + try { + return sub.currentContext(); + } + catch (Exception ex) { + if (log.isDebugEnabled()) { + log.debug("Exception occurred while trying to retrieve the context", ex); + } + } + return Context.empty(); + } + static String name(CoreSubscriber sub) { return Scannable.from(sub).name(); } diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java index 90ff81af6..75a29a486 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java @@ -106,6 +106,33 @@ public abstract class ScopePassingSpanSubscriberTests { } }; + Subscriber exceptionThrowingPassingSpanSubscriber = new CoreSubscriber() { + @Override + public void onSubscribe(Subscription s) { + + } + + @Override + public void onNext(Object o) { + + } + + @Override + public void onError(Throwable t) { + + } + + @Override + public void onComplete() { + + } + + @Override + public Context currentContext() { + throw new NullPointerException("Boom!"); + } + }; + AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(); @BeforeEach @@ -152,6 +179,14 @@ public abstract class ScopePassingSpanSubscriberTests { then(subscriber.currentContext().isEmpty()).isTrue(); } + @org.junit.Test + public void should_set_empty_context_when_exception_occurs_while_trying_to_retrieve_the_context() { + ScopePassingSpanSubscriber subscriber = new ScopePassingSpanSubscriber<>(null, Context.empty(), + currentTraceContext(), null); + + then(subscriber.currentContext().isEmpty()).isTrue(); + } + @Test public void should_put_current_span_to_context() { try (CurrentTraceContext.Scope ws = currentTraceContext().newScope(context2())) {