Skip to content

Commit

Permalink
contrib/gorilla/mux: Add WithStatusCheck()
Browse files Browse the repository at this point in the history
Add WithStatusCheck() to contrib/gorilla/mux so that the function can be
passed to httptrace.ServeConfig.IsStatusError.

Fixes #2390
  • Loading branch information
winebarrel committed Feb 8, 2025
1 parent e08fe35 commit 4c27262
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
15 changes: 8 additions & 7 deletions contrib/gorilla/mux/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,14 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
spanopts = append(spanopts, httptraceinternal.HeaderTagsFromRequest(req, r.config.headerTags))
resource := r.config.resourceNamer(r, req)
httptrace.TraceAndServe(r.Router, w, req, &httptrace.ServeConfig{
Service: r.config.serviceName,
Resource: resource,
FinishOpts: r.config.finishOpts,
SpanOpts: spanopts,
QueryParams: r.config.queryParams,
RouteParams: match.Vars,
Route: route,
Service: r.config.serviceName,
Resource: resource,
FinishOpts: r.config.finishOpts,
SpanOpts: spanopts,
QueryParams: r.config.queryParams,
RouteParams: match.Vars,
Route: route,
IsStatusError: r.config.isStatusError,
})
}

Expand Down
42 changes: 42 additions & 0 deletions contrib/gorilla/mux/mux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,48 @@ func TestWithQueryParams(t *testing.T) {
assert.Equal("http://localhost/200?<redacted>&id=3&name=5", mt.FinishedSpans()[0].Tags()[ext.HTTPURL])
}

func TestWithStatusCheck(t *testing.T) {
for _, ht := range []struct {
name string
code int
hasErr bool
isStatusError func(statusCode int) bool
}{
{
name: "without-statuscheck",
code: http.StatusInternalServerError,
hasErr: true,
isStatusError: nil,
},
{
name: "with-statuscheck",
code: http.StatusInternalServerError,
hasErr: false,
isStatusError: func(statusCode int) bool { return false },
},
} {
t.Run(ht.name, func(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
defer mt.Stop()

r := httptest.NewRequest("GET", "/500", nil)
w := httptest.NewRecorder()
mux := NewRouter(WithStatusCheck(ht.isStatusError))
mux.Handle("/500", errorHandler(http.StatusInternalServerError))
mux.ServeHTTP(w, r)
assert.Equal(ht.code, http.StatusInternalServerError)

spans := mt.FinishedSpans()
assert.Equal(1, len(spans))

s := spans[0]
_, ok := s.Tag(ext.Error).(error)
assert.Equal(ht.hasErr, ok)
})
}
}

func TestSpanOptions(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
Expand Down
9 changes: 9 additions & 0 deletions contrib/gorilla/mux/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type routerConfig struct {
ignoreRequest func(*http.Request) bool
queryParams bool
headerTags *internal.LockMap
isStatusError func(statusCode int) bool
}

// RouterOption represents an option that can be passed to NewRouter.
Expand Down Expand Up @@ -140,3 +141,11 @@ func WithQueryParams() RouterOption {
cfg.queryParams = true
}
}

// WithStatusCheck specifies a function fn which reports whether the passed
// statusCode should be considered an error.
func WithStatusCheck(fn func(statusCode int) bool) RouterOption {
return func(cfg *routerConfig) {
cfg.isStatusError = fn
}
}

0 comments on commit 4c27262

Please sign in to comment.