diff --git a/errors.go b/errors.go index 59fff04..4788b18 100644 --- a/errors.go +++ b/errors.go @@ -1,6 +1,7 @@ package jsonapi import ( + "encoding/json" "errors" "fmt" "sort" @@ -89,11 +90,16 @@ type ErrorSource struct { Parameter string `json:"parameter,omitempty"` } +// Status provides a helper for setting an Error.Status value. +func Status(s int) *int { + return &s +} + // Error represents a JSON:API error object as defined by https://jsonapi.org/format/1.0/#error-objects. type Error struct { ID string `json:"id,omitempty"` Links *ErrorLink `json:"links,omitempty"` - Status string `json:"status,omitempty"` + Status *int `json:"status,omitempty"` Code string `json:"code,omitempty"` Title string `json:"title,omitempty"` Detail string `json:"detail,omitempty"` @@ -101,6 +107,23 @@ type Error struct { Meta any `json:"meta,omitempty"` } +// MarshalJSON implements the json.Marshaler interface. +func (e *Error) MarshalJSON() ([]byte, error) { + var status string + if e.Status != nil { + status = fmt.Sprintf("%d", *e.Status) + } + + type alias Error + return json.Marshal(&struct { + Status string `json:"status,omitempty"` + *alias + }{ + Status: status, + alias: (*alias)(e), + }) +} + // Error implements the error interface. func (e *Error) Error() string { return fmt.Sprintf("%s: %s", e.Title, e.Detail) diff --git a/jsonapi_test.go b/jsonapi_test.go index 2e6a673..016ba3e 100644 --- a/jsonapi_test.go +++ b/jsonapi_test.go @@ -2,6 +2,7 @@ package jsonapi import ( "fmt" + "net/http" "strconv" "time" ) @@ -106,7 +107,7 @@ var ( errorsComplexStruct = Error{ //nolint: errname ID: "1", Links: &ErrorLink{About: "A"}, - Status: "S", + Status: Status(http.StatusInternalServerError), Code: "C", Title: "T", Detail: "D", @@ -130,8 +131,8 @@ var ( // error bodies errorsSimpleStructBody = `{"errors":[{"title":"T"}]}` - errorsComplexStructBody = `{"errors":[{"id":"1","links":{"about":"A"},"status":"S","code":"C","title":"T","detail":"D","source":{"pointer":"PO","parameter":"PA"},"meta":{"K":"V"}}]}` - errorsComplexSliceManyBody = `{"errors":[{"title":"T"},{"id":"1","links":{"about":"A"},"status":"S","code":"C","title":"T","detail":"D","source":{"pointer":"PO","parameter":"PA"},"meta":{"K":"V"}}]}` + errorsComplexStructBody = `{"errors":[{"id":"1","links":{"about":"A"},"status":"500","code":"C","title":"T","detail":"D","source":{"pointer":"PO","parameter":"PA"},"meta":{"K":"V"}}]}` + errorsComplexSliceManyBody = `{"errors":[{"title":"T"},{"id":"1","links":{"about":"A"},"status":"500","code":"C","title":"T","detail":"D","source":{"pointer":"PO","parameter":"PA"},"meta":{"K":"V"}}]}` errorsWithLinkObjectBody = `{"errors":[{"links":{"about":{"href":"A","meta":{"key_i":420,"key_s":"B"}}}}]}` )