/** * Returns the value that should be used for the "error" {@link com.nike.wingtips.Span#putTag(String, String)} * associated with the given response, or null if this response does not indicate an error. The criteria for * determining an error can change depending on whether it's a client span or server span, or there may even be * project-specific logic. * * <p>By default, this method considers a response to indicate an error if the {@link * #getResponseHttpStatus(Object)} is greater than or equal to 400, and will return that status code as a string. * This is a client-span-centric view - implementations of this class that represent server spans may want to * override this to have it only consider status codes greater than or equal to 500 to be errors. * * <p>NOTE: It's important that you return something non-empty and non-blank if want the span to be considered an * error. In particular, empty strings or strings that consist of only whitespace may be treated by callers * of this method the same as {@code null}. * * @param response The response object to be inspected - <b>this may be null!</b> * * @return The value that should be used for the "error" {@link com.nike.wingtips.Span#putTag(String, String)} * associated with the given response, or null if this response does not indicate an error. */ public @Nullable String getErrorResponseTagValue(@Nullable RES response) { Integer statusCode = getResponseHttpStatus(response); if (statusCode != null && statusCode >= 400) { return statusCode.toString(); } // Status code does not indicate an error, so return null. return null; }
@Override protected void doHandleResponseAndErrorTagging( @NotNull Span span, @Nullable REQ request, @Nullable RES response, @Nullable Throwable error, @NotNull HttpTagAndSpanNamingAdapter<REQ, RES> adapter ) { putTagIfValueIsNotBlank(span, KnownOpenTracingTags.HTTP_STATUS, adapter.getResponseHttpStatus(response)); if (error != null || StringUtils.isNotBlank(adapter.getErrorResponseTagValue(response))) { // OpenTracing doesn't expect you to pass messages with the error tag, just error=true. // So we don't need to do anything with the given error Throwable or returned // getErrorResponseTagValue(), other than have them trigger adding the error=true tag. span.putTag(KnownOpenTracingTags.ERROR, "true"); } } }
@Override protected void doHandleResponseAndErrorTagging( @NotNull Span span, @Nullable REQ request, @Nullable RES response, @Nullable Throwable error, @NotNull HttpTagAndSpanNamingAdapter<REQ, RES> adapter ) { // Now that we have both request and response, we'll re-try to get the route. putTagIfValueIsNotBlank(span, KnownZipkinTags.HTTP_ROUTE, adapter.getRequestUriPathTemplate(request, response)); putTagIfValueIsNotBlank(span, KnownZipkinTags.HTTP_STATUS_CODE, adapter.getResponseHttpStatus(response)); // For error tagging, we'll defer to the error Throwable if it's not null. if (error != null) { String message = error.getMessage(); if (message == null) { message = error.getClass().getSimpleName(); } addErrorTagToSpan(span, message); } else { // The error Throwable was null, so we'll see if the adapter thinks this is an error response. String errorTagValue = adapter.getErrorResponseTagValue(response); if (StringUtils.isNotBlank(errorTagValue)) { addErrorTagToSpan(span, errorTagValue); } } }
String httpMethod = (adapter == null) ? null : adapter.getRequestHttpMethod(request); String pathTemplate = (adapter == null) ? null : adapter.getRequestUriPathTemplate(request, response); Integer responseStatusCode = (adapter == null) ? null : adapter.getResponseHttpStatus(response);
@DataProvider(value = { "null | null", "0 | null", "100 | null", "200 | null", "300 | null", "399 | null", "400 | 400", "499 | 499", "500 | 500", "599 | 599", "999 | 999", }, splitBy = "\\|") @Test public void getErrorResponseTagValue_works_as_expected(Integer responseStatusCode, String expectedReturnVal) { // given doReturn(responseStatusCode).when(implSpy).getResponseHttpStatus(anyObject()); // when // Null response object makes no difference - it's entirely dependent on what getResponseHttpStatus() returns. String resultForNonNullResponseObj = implSpy.getErrorResponseTagValue(new Object()); String resultForNullResponseObj = implSpy.getErrorResponseTagValue(null); // then assertThat(resultForNonNullResponseObj).isEqualTo(expectedReturnVal); assertThat(resultForNullResponseObj).isEqualTo(expectedReturnVal); }
doReturn(adapterHttpStatus).when(adapterMock).getResponseHttpStatus(anyObject()); verify(adapterMock).getResponseHttpStatus(responseMock);
doReturn(statusCode).when(adapterMock).getResponseHttpStatus(anyObject()); verify(adapterMock).getResponseHttpStatus(responseMock); verifyNoMoreInteractions(adapterMock); verifyZeroInteractions(requestMock, responseMock);
String adapterRoute = "route-" + UUID.randomUUID().toString(); doReturn(adapterHttpStatus).when(adapterMock).getResponseHttpStatus(anyObject()); doReturn(adapterRoute).when(adapterMock).getRequestUriPathTemplate(anyObject(), anyObject()); verify(adapterMock).getResponseHttpStatus(responseMock);
doReturn(httpMethod).when(implSpy).getRequestHttpMethod(anyObject()); doReturn(pathTemplate).when(implSpy).getRequestUriPathTemplate(anyObject(), anyObject()); doReturn(responseStatusCode).when(implSpy).getResponseHttpStatus(anyObject());