Skip to content

Commit 6ef6c30

Browse files
authored
Catch our blocking exception when it is nested. Eg. spring framework. (#373)
* Catch our blocking exception when it is nested. Eg. spring framework. * Add test * Running spotlessapply
1 parent 0a08c9c commit 6ef6c30

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

instrumentation/servlet/servlet-3.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30AndFilterInstrumentation.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,16 @@ public static void exit(
205205
}
206206
}
207207
} finally {
208-
if (throwable instanceof HypertraceEvaluationException) {
209-
httpResponse.setStatus(403);
210-
// bytebuddy treats the reassignment of this variable to null as an instruction to
211-
// suppress
212-
// this exception, which is what we want
213-
throwable = null;
208+
Throwable tmp = throwable;
209+
while (tmp != null) { // loop in case our exception is nested (eg. springframework)
210+
if (tmp instanceof HypertraceEvaluationException) {
211+
httpResponse.setStatus(403);
212+
// bytebuddy treats the reassignment of this variable to null as an instruction to
213+
// suppress this exception, which is what we want
214+
throwable = null;
215+
break;
216+
}
217+
tmp = tmp.getCause();
214218
}
215219
}
216220
}

instrumentation/servlet/servlet-3.0/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/servlet/v3_0/nowrapping/Servlet30InstrumentationTest.java

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.EchoWriter_single_char;
2828
import io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.v3_0.nowrapping.TestServlets.GetHello;
2929
import io.opentelemetry.sdk.trace.data.SpanData;
30+
import java.io.IOException;
3031
import java.util.EnumSet;
3132
import java.util.List;
32-
import javax.servlet.DispatcherType;
33+
import javax.servlet.*;
3334
import okhttp3.FormBody;
3435
import okhttp3.MediaType;
3536
import okhttp3.Request;
@@ -38,6 +39,7 @@
3839
import org.WrappingFilter;
3940
import org.eclipse.jetty.server.Server;
4041
import org.eclipse.jetty.servlet.ServletContextHandler;
42+
import org.hypertrace.agent.core.instrumentation.HypertraceEvaluationException;
4143
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
4244
import org.hypertrace.agent.testing.AbstractInstrumenterTest;
4345
import org.junit.jupiter.api.AfterAll;
@@ -53,6 +55,31 @@ public class Servlet30InstrumentationTest extends AbstractInstrumenterTest {
5355
private static Server server = new Server(0);
5456
private static int serverPort;
5557

58+
/*
59+
* Filter that mimics the spring framework. It will catch and wrap our blocking exception
60+
*/
61+
public static class WrapExceptionFilter implements Filter {
62+
@Override
63+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
64+
throws IOException, ServletException {
65+
System.out.print("hello from filter");
66+
try {
67+
chain.doFilter(request, response);
68+
} catch (Throwable t) {
69+
if (t instanceof HypertraceEvaluationException) {
70+
throw new RuntimeException("wrapped exception", t);
71+
}
72+
throw t;
73+
}
74+
}
75+
76+
@Override
77+
public void init(FilterConfig arg0) throws ServletException {}
78+
79+
@Override
80+
public void destroy() {}
81+
}
82+
5683
@BeforeAll
5784
public static void startServer() throws Exception {
5885
ServletContextHandler handler = new ServletContextHandler();
@@ -62,6 +89,8 @@ public static void startServer() throws Exception {
6289
handler.addServlet(GetHello.class, "/hello");
6390
handler.addServlet(EchoStream_single_byte.class, "/echo_stream_single_byte");
6491
handler.addServlet(EchoStream_arr.class, "/echo_stream_arr");
92+
handler.addFilter(
93+
WrapExceptionFilter.class, "/echo_stream_arr", EnumSet.of(DispatcherType.REQUEST));
6594
handler.addServlet(EchoStream_arr_offset.class, "/echo_stream_arr_offset");
6695
handler.addServlet(EchoStream_readLine_print.class, "/echo_stream_readLine_print");
6796
handler.addServlet(EchoWriter_single_char.class, "/echo_writer_single_char");
@@ -296,6 +325,35 @@ public void blockBody() throws Exception {
296325
spanData.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY));
297326
}
298327

328+
@Test
329+
public void blockBodyWrappedException() throws Exception {
330+
FormBody formBody = new FormBody.Builder().add("block", "true").build();
331+
Request request =
332+
new Request.Builder()
333+
.url(String.format("http://localhost:%d/echo_stream_arr", serverPort))
334+
.post(formBody)
335+
.header(REQUEST_HEADER, REQUEST_HEADER_VALUE)
336+
.build();
337+
try (Response response = httpClient.newCall(request).execute()) {
338+
Assertions.assertEquals(403, response.code());
339+
}
340+
341+
TEST_WRITER.waitForTraces(1);
342+
List<List<SpanData>> traces = TEST_WRITER.getTraces();
343+
Assertions.assertEquals(1, traces.size());
344+
List<SpanData> spans = traces.get(0);
345+
Assertions.assertEquals(1, spans.size());
346+
SpanData spanData = spans.get(0);
347+
Assertions.assertNull(
348+
spanData
349+
.getAttributes()
350+
.get(HypertraceSemanticAttributes.httpResponseHeader(TestServlets.RESPONSE_HEADER)));
351+
Assertions.assertEquals(
352+
"block=true", spanData.getAttributes().get(HypertraceSemanticAttributes.HTTP_REQUEST_BODY));
353+
Assertions.assertNull(
354+
spanData.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY));
355+
}
356+
299357
public void postJson(String url) throws Exception {
300358
Request request =
301359
new Request.Builder()

0 commit comments

Comments
 (0)