github.com/go-kivik/kivik/v4@v4.3.2/x/kivikd/couchserver/errors.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 //go:build !js 14 15 package couchserver 16 17 import ( 18 "encoding/json" 19 "errors" 20 "fmt" 21 "net/http" 22 23 "github.com/go-kivik/kivik/v4" 24 internal "github.com/go-kivik/kivik/v4/int/errors" 25 ) 26 27 func errorDescription(status int) string { 28 switch status { 29 case http.StatusUnauthorized: 30 return "unauthorized" 31 case http.StatusBadRequest: 32 return "bad_request" 33 case http.StatusNotFound: 34 return "not_found" 35 case http.StatusInternalServerError: 36 return "internal_server_error" // TODO: Validate that this is normative 37 case http.StatusNotImplemented: 38 return "not_implemented" // Non-standard 39 } 40 panic(fmt.Sprintf("unknown status %d", status)) 41 } 42 43 type couchError struct { 44 Error string `json:"error"` 45 Reason string `json:"reason"` 46 } 47 48 // HandleError returns a CouchDB-formatted error. It does nothing if err is nil. 49 func (h *Handler) HandleError(w http.ResponseWriter, err error) { 50 if err == nil { 51 return 52 } 53 status := kivik.HTTPStatus(err) 54 w.WriteHeader(status) 55 var reason string 56 kerr := new(internal.Error) 57 if errors.As(err, &kerr) { 58 reason = kerr.Message 59 } else { 60 reason = err.Error() 61 } 62 wErr := json.NewEncoder(w).Encode(couchError{ 63 Error: errorDescription(status), 64 Reason: reason, 65 }) 66 if wErr != nil { 67 h.Logger.Printf("Failed to send send error: %s", wErr) 68 } 69 }