-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[query] Allow injecting function for rewriting error response #3008
Changes from 2 commits
9a51ac1
648ec1d
867aea8
6fb565d
c5a937a
9f900ae
184fb8b
a050331
bb301d7
f05f3d4
2631711
4bcc525
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,10 +25,19 @@ import ( | |
"encoding/json" | ||
"errors" | ||
"net/http" | ||
"sync" | ||
|
||
xerrors "github.com/m3db/m3/src/x/errors" | ||
) | ||
|
||
// ErrorRewriteFn is a function for rewriting response error | ||
type ErrorRewriteFn func(error) error | ||
|
||
var ( | ||
_errorRewriteFn ErrorRewriteFn = func(err error) error { return err } | ||
_errorRewriteFnLock sync.Mutex | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We tend not to use underscores for package local variables. Just use a non-exported (lowercase) letter to begin with. e.g. errorRewriteFn
errorRewriteFnLock There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
) | ||
|
||
// Error is an HTTP JSON error that also sets a return status code. | ||
type Error interface { | ||
// Fulfill error interface. | ||
|
@@ -92,6 +101,8 @@ func WriteError(w http.ResponseWriter, err error, opts ...WriteErrorOption) { | |
fn(&o) | ||
} | ||
|
||
err = _errorRewriteFn(err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to hold the read lock to get the error function without causing a race. e.g. _errorRewriteFnLock.RLock()
err = _errorRewriteFn(err)
_errorRewriteFnLock.RUnlock() There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
statusCode := getStatusCode(err) | ||
if o.response == nil { | ||
w.Header().Set(HeaderContentType, ContentTypeJSON) | ||
|
@@ -103,6 +114,21 @@ func WriteError(w http.ResponseWriter, err error, opts ...WriteErrorOption) { | |
} | ||
} | ||
|
||
// GetErrorRewriteFn returns the error rewrite function | ||
func GetErrorRewriteFn() ErrorRewriteFn { | ||
return _errorRewriteFn | ||
} | ||
|
||
// SetErrorRewriteFn sets error rewrite function | ||
func SetErrorRewriteFn(f ErrorRewriteFn) ErrorRewriteFn { | ||
_errorRewriteFnLock.Lock() | ||
defer _errorRewriteFnLock.Unlock() | ||
|
||
res := _errorRewriteFn | ||
_errorRewriteFn = f | ||
return res | ||
} | ||
|
||
func getStatusCode(err error) int { | ||
switch v := err.(type) { | ||
case Error: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, can't we just rewrite in
xhttp.WriteError
which the err is passed into on line 108 here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alas,
xhttp.WithErrorResponse(b)
passes already serialized error message, which is then directly written to HTTP response. Hence the rewrite insideWriteError()
would only affect status code, the message would stay as in original error.I was considering changing
xhttp.WithErrorResponse()
to accept afunc(error) []byte
instead of already prepared[]byte
. What do you think about that?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After #2933, both
RespondError()
andWriteError()
emitsstatus
field. Thus, the latter can be used directly6fb565d#diff-dcc137769b5c2ad03409d297cf05413b71396fc7df31a9a2ee6ecb9a9b20e22dL95-R95