Files
Cyrene_v2/internal/errors/http.go
T

46 lines
1.3 KiB
Go

package errors
import (
stdErrors "errors"
"net/http"
)
// HTTPStatus resolves the HTTP status code for err.
//
// If err (or anything wrapped by it) is an AppError with a non-zero HTTPCode,
// that code is returned; otherwise the fallback is http.StatusInternalServerError
// (500). New and Wrap propagate the cause's status, so wrapping a sentinel such
// as ErrNotFound keeps status 404.
func HTTPStatus(err error) int {
var appErr *AppError
if stdErrors.As(err, &appErr) && appErr.HTTPCode != 0 {
return appErr.HTTPCode
}
return http.StatusInternalServerError
}
// ToJSON renders err as an RFC 7807 style error object, aligned with the client
// API contract {error:{code,message}}.
//
// For an AppError (or one wrapped by it) the Code and Message are returned
// verbatim. For any other error a generic internal error is returned so that
// internal details are never leaked to the user; the underlying error is kept
// only in the Cause field for logging.
func ToJSON(err error) map[string]any {
var appErr *AppError
if stdErrors.As(err, &appErr) {
return map[string]any{
"error": map[string]any{
"code": appErr.Code,
"message": appErr.Message,
},
}
}
return map[string]any{
"error": map[string]any{
"code": ErrInternal.Code,
"message": ErrInternal.Message,
},
}
}