WriteErrorCode function always returns 500 code inside JSON payload
Preflight checklist
- [x] I could not find a solution in the existing issues, docs, nor discussions.
- [x] I agree to follow this project's Code of Conduct.
- [x] I have read and am following this repository's Contribution Guidelines.
- [x] I have joined the Ory Community Slack.
- [x] I am signed up to the Ory Security Patch Newsletter.
Describe the bug
I noticed by using the (h *JSONWriter) WriteErrorCode function, that the header is correctly set, but the JSON response returns a 500 status code and message.
Is this a bug or am i interpreting the purpose of the function wrong?
Reproducing the bug
h.d.Writer().WriteErrorCode(w, r, 401, errors.New("error"))
Response:
Version
v0.10.2
On which operating system are you observing this issue?
Linux
In which environment are you deploying?
None
Additional Context
My workaround right now:
h.d.Writer().WriteError(w, r, herodot.DefaultError{
CodeField: 401,
ErrorField: errors.New("error"),
})
func defaultJSONErrorEnhancer(r *http.Request, err error) interface{} {
if e, ok := err.(ErrorEnhancer); ok {
return e.EnhanceJSONError()
}
return &ErrorContainer{Error: ToDefaultError(err, r.Header.Get("X-Request-ID"))}
}
func ToDefaultError(err error, requestID string) *DefaultError {
de := &DefaultError{
RIDField: requestID,
CodeField: http.StatusInternalServerError,
DetailsField: map[string]interface{}{},
ErrorField: err.Error(),
}
de.Wrap(err)
if c := ReasonCarrier(nil); stderr.As(err, &c) {
de.ReasonField = c.Reason()
}
if c := RequestIDCarrier(nil); stderr.As(err, &c) && c.RequestID() != "" {
de.RIDField = c.RequestID()
}
if c := DetailsCarrier(nil); stderr.As(err, &c) && c.Details() != nil {
de.DetailsField = c.Details()
}
if c := StatusCarrier(nil); stderr.As(err, &c) && c.Status() != "" {
de.StatusField = c.Status()
}
if c := StatusCodeCarrier(nil); stderr.As(err, &c) && c.StatusCode() != 0 {
de.CodeField = c.StatusCode()
}
if c := DebugCarrier(nil); stderr.As(err, &c) {
de.DebugField = c.Debug()
}
if c := IDCarrier(nil); stderr.As(err, &c) {
de.IDField = c.ID()
}
if de.StatusField == "" {
de.StatusField = http.StatusText(de.StatusCode())
}
return de
}
I think the problem may come from here.
I'm not sure how that's possible, the code is pretty clear on which status code is being sent: https://github.com/ory/herodot/blob/07b33b42390e7534213a1f72e760f8f367677017/json.go#L162
@aeneasr When initializing h := NewJSONWriter(nil), it will create a default object ErrorContainer{Error: ToDefaultError(err, r.Header.Get("X-Request-ID"))}.
func NewJSONWriter(reporter ErrorReporter) *JSONWriter {
writer := &JSONWriter{
Reporter: reporter,
ErrorEnhancer: defaultJSONErrorEnhancer,
}
if writer.Reporter == nil {
writer.Reporter = &stdReporter{}
}
writer.ErrorEnhancer = defaultJSONErrorEnhancer
return writer
}