HttpParser { public <Resp> void response(HttpAdapter<?, Resp> adapter, @Nullable Resp res, @Nullable Throwable error, SpanCustomizer customizer) { int statusCode = 0; if (res != null) { statusCode = adapter.statusCodeAsInt(res); String nameFromRoute = spanNameFromRoute(adapter, res, statusCode); if (nameFromRoute != null) customizer.name(nameFromRoute); String maybeStatus = maybeStatusAsString(statusCode, 299); if (maybeStatus != null) customizer.tag("http.status_code", maybeStatus); } error(statusCode, error, customizer); }  void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer); void response(HttpAdapter<?, Resp> adapter, @Nullable Resp res,
    @Nullable Throwable error, SpanCustomizer customizer);  }
@Test public void response_tagsStatusAndErrorOnResponseCode() { when(adapter.statusCodeAsInt(response)).thenReturn(400); parser.response(adapter, response, null, customizer); verify(customizer).tag("http.status_code", "400"); verify(customizer).tag("error", "400"); }
@Test public void response_statusZeroIsNotAnError() { when(adapter.statusCodeAsInt(response)).thenReturn(0); parser.response(adapter, response, null, customizer); verify(customizer, never()).tag("http.status_code", "0"); verify(customizer, never()).tag("error", "0"); }
@Test public void response_status101IsNotAnError() { when(adapter.statusCodeAsInt(response)).thenReturn(101); parser.response(adapter, response, null, customizer); verify(customizer).tag("http.status_code", "101"); verify(customizer, never()).tag("error", "101"); }
@Test public void response_tagsErrorFromException() { parser.response(adapter, response, new RuntimeException("drat"), customizer); verify(customizer).tag("error", "drat"); }
@Test public void response_tagsErrorPrefersExceptionVsResponseCode() { when(adapter.statusCodeAsInt(response)).thenReturn(400); parser.response(adapter, response, new RuntimeException("drat"), customizer); verify(customizer).tag("error", "drat"); }
@Test public void response_tagsErrorOnExceptionEvenIfStatusOk() { when(adapter.statusCodeAsInt(response)).thenReturn(200); parser.response(adapter, response, new RuntimeException("drat"), customizer); verify(customizer).tag("error", "drat"); }
@Test public void routeBasedName() { when(adapter.methodFromResponse(response)).thenReturn("GET"); when(adapter.route(response)).thenReturn("/users/:userId"); when(adapter.statusCodeAsInt(response)).thenReturn(200); parser.response(adapter, response, null, customizer); verify(customizer).name("GET /users/:userId"); }
@Test public void routeBasedName_redirect() { when(adapter.methodFromResponse(response)).thenReturn("GET"); when(adapter.route(response)).thenReturn(""); when(adapter.statusCodeAsInt(response)).thenReturn(307); parser.response(adapter, response, null, customizer); verify(customizer).name("GET redirected"); }
@Test public void routeBasedName_notFound() { when(adapter.methodFromResponse(response)).thenReturn("DELETE"); when(adapter.route(response)).thenReturn(""); when(adapter.statusCodeAsInt(response)).thenReturn(404); parser.response(adapter, response, null, customizer); verify(customizer).name("DELETE not_found"); }
@Test public void routeBasedName_skipsOnMissingData() { when(adapter.methodFromResponse(response)).thenReturn("DELETE"); when(adapter.route(response)).thenReturn(null); when(adapter.statusCodeAsInt(response)).thenReturn(404); parser.response(adapter, response, null, customizer); verify(customizer, never()).name(any(String.class)); }