package http import ( "encoding/json" "fmt" "net/http" ) // Return an error over an http connection. // The error will have the given return code `code` // and a json encoded body with the field "id" set to `errId` // and a field "message" set to the `message` // // Deprecated: Use ProblemDetails or ProblemDetailsStatusOnly instead func HttpErr(w http.ResponseWriter, errId int, message string, code int) { w.WriteHeader(code) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, "{\"id\": %d, \"message\": \"%s\"}", errId, message) } // Write an RFC 9457 compliant problem details response // If details is not nil, it will be included. // If extras is not nil, each key-value pair will be included at // the root layer. // Keys in extras that would overwrite the default elements will be ignored. // Those would be "type", "status", "title" and "detail" func ProblemDetails( w http.ResponseWriter, statusCode int, errorType string, errorTitle string, details *string, extras map[string]any, ) { w.Header().Add("Content-Type", "application/problem+json") w.WriteHeader(statusCode) data := map[string]any{ "type": errorType, "status": statusCode, "title": errorTitle, } if details != nil { data["detail"] = *details } if extras != nil { for k, v := range extras { if _, ok := data[k]; ok { // Don't overwrite default fields continue } data[k] = v } } enc := json.NewEncoder(w) enc.Encode(data) } // Write a simple problem details response. // It only provides the status code, as defined in RFC 9457, section 4.2.1 func ProblemDetailsStatusOnly(w http.ResponseWriter, statusCode int) { w.Header().Add("Content-Type", "application/problem+json") w.WriteHeader(statusCode) data := map[string]any{ "type": "about:blank", "title": http.StatusText(statusCode), "status": statusCode, "reference": "RFC 9457", } enc := json.NewEncoder(w) enc.Encode(data) }