Skip to content

Commit

Permalink
Changed RoundTripper implementation to treat 4xx as errors, not 5xx. …
Browse files Browse the repository at this point in the history
…Amended tests accordingly
  • Loading branch information
mtoffl01 committed Sep 19, 2024
1 parent dbd61d2 commit 07b829f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 31 deletions.
6 changes: 2 additions & 4 deletions contrib/net/http/roundtripper.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,9 @@ func (rt *roundTripper) RoundTrip(req *http.Request) (res *http.Response, err er
span.SetTag(ext.Error, err)
}
} else {
fmt.Println("MTOFF: Settnig http status code")
span.SetTag(ext.HTTPCode, strconv.Itoa(res.StatusCode))
// treat 5XX & 4xx as errors
// TODO: Client spans should only have errors on 4xx, so change this to just 4xx
if sc := res.StatusCode / 100; sc == 5 || sc == 4 {
// Client spans consider 4xx as errors
if res.StatusCode/100 == 4 {
span.SetTag("http.errors", res.Status)
span.SetTag(ext.Error, fmt.Errorf("%d: %s", res.StatusCode, http.StatusText(res.StatusCode)))
} else {
Expand Down
35 changes: 12 additions & 23 deletions contrib/net/http/roundtripper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func TestRoundTripper(t *testing.T) {
assert.Equal(t, wantPort, s1.Tag(ext.NetworkDestinationPort))
}

// Assert all error tags exist when status code is 4xx
func TestRoundTripperClientError(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()
Expand Down Expand Up @@ -127,23 +128,21 @@ func TestRoundTripperClientError(t *testing.T) {
defer resp.Body.Close()

spans := mt.FinishedSpans()
assert.Len(t, spans, 1)
s1 := spans[0]
assert.Equal(t, "400", s1.Tag(ext.HTTPCode))
assert.Equal(t, true, s1.Tag(ext.Error))
assert.Equal(t, "*errors.errorString", s1.Tag(ext.ErrorType))
assert.Equal(t, "400: Bad Request", s1.Tag(ext.ErrorMsg))
assert.NotEmpty(t, s1.Tag(ext.ErrorStack))
}

// Assert no error tags are set when status code is 5xx
func TestRoundTripperServerError(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
spanctx, err := tracer.Extract(tracer.HTTPHeadersCarrier(r.Header))
assert.NoError(t, err)

span := tracer.StartSpan("test",
tracer.ChildOf(spanctx))
defer span.Finish()

w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Error"))
}))
Expand All @@ -166,24 +165,14 @@ func TestRoundTripperServerError(t *testing.T) {
defer resp.Body.Close()

spans := mt.FinishedSpans()
assert.Len(t, spans, 2)
assert.Equal(t, spans[0].TraceID(), spans[1].TraceID())

s0 := spans[0]
assert.Equal(t, "test", s0.OperationName())
assert.Equal(t, "test", s0.Tag(ext.ResourceName))
assert.Len(t, spans, 1)

s1 := spans[1]
assert.Equal(t, "http.request", s1.OperationName())
assert.Equal(t, "http.request", s1.Tag(ext.ResourceName))
s1 := spans[0]
assert.Equal(t, "500", s1.Tag(ext.HTTPCode))
assert.Equal(t, "GET", s1.Tag(ext.HTTPMethod))
assert.Equal(t, s.URL+"/hello/world", s1.Tag(ext.HTTPURL))
assert.Equal(t, fmt.Errorf("500: Internal Server Error"), s1.Tag(ext.Error))
assert.Equal(t, true, s1.Tag("CalledBefore"))
assert.Equal(t, true, s1.Tag("CalledAfter"))
assert.Equal(t, ext.SpanKindClient, s1.Tag(ext.SpanKind))
assert.Equal(t, "net/http", s1.Tag(ext.Component))
assert.Empty(t, s1.Tag(ext.Error))
assert.Empty(t, s1.Tag(ext.ErrorMsg))
assert.Empty(t, s1.Tag(ext.ErrorType))
assert.Empty(t, s1.Tag(ext.ErrorStack))
}

func TestRoundTripperNetworkError(t *testing.T) {
Expand Down
10 changes: 6 additions & 4 deletions ddtrace/mocktracer/mockspan.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,14 @@ func (s *mockspan) SetTag(key string, value interface{}) {
}
}

func (m *mockspan) setTagError(value interface{}) {
func (s *mockspan) setTagError(value interface{}) {
switch v := value.(type) {
case error:
m.tags[ext.Error] = true
m.tags[ext.ErrorMsg] = v.Error()
m.tags[ext.ErrorType] = reflect.TypeOf(v).String()
s.tags[ext.Error] = true
s.tags[ext.ErrorMsg] = v.Error()
s.tags[ext.ErrorType] = reflect.TypeOf(v).String()
// Note: This method has been simplified to set a dummy stack trace. It also ignores the noDebugStack setting.
s.tags[ext.ErrorStack] = v.Error()
}
}

Expand Down

0 comments on commit 07b829f

Please sign in to comment.