1
// Copyright 2022 The CubeFS Authors.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
27
// Error implements HTTPError
29
Status int // http status code
30
Code string // error code
34
// errorResponse response error with json
35
// internal type between server and client
36
errorResponse struct {
37
Error string `json:"error"`
38
Code string `json:"code,omitempty"`
41
statusCoder interface {
44
errorCoder interface {
49
var _ HTTPError = &Error{}
51
// NewError new error with
52
func NewError(statusCode int, errCode string, err error) *Error {
60
// StatusCode returns http status code
61
func (e *Error) StatusCode() int {
65
// ErrorCode returns special defined code
66
func (e *Error) ErrorCode() string {
70
// Error implements error
71
func (e *Error) Error() string {
78
// Unwrap errors.Is(), errors.As() and errors.Unwrap()
79
func (e *Error) Unwrap() error {
83
// DetectStatusCode returns http status code
84
func DetectStatusCode(err error) int {
90
if errors.As(err, &st) {
91
return st.StatusCode()
96
return http.StatusBadRequest
97
case context.Canceled:
100
return http.StatusInternalServerError
104
// DetectErrorCode returns error code
105
func DetectErrorCode(err error) string {
111
if errors.As(err, &ec) {
112
return ec.ErrorCode()
118
case context.Canceled:
121
return "InternalServerError"
125
// DetectError returns status code, error code, error
126
func DetectError(err error) (int, string, error) {
127
return DetectStatusCode(err), DetectErrorCode(err), errors.Unwrap(err)
130
// Error2HTTPError returns an interface HTTPError from an error
131
func Error2HTTPError(err error) HTTPError {
135
if httpErr, ok := err.(HTTPError); ok {
139
status, code, _ := DetectError(err)
140
return NewError(status, code, err)
143
// ReplyErr directly reply error with response writer
144
func ReplyErr(w http.ResponseWriter, code int, err string) {
145
msg, _ := json.Marshal(NewError(code, "", errors.New(err)))
147
h.Set("Content-Length", strconv.Itoa(len(msg)))
148
h.Set("Content-Type", MIMEJSON)
153
// ReplyWith directly reply body with response writer
154
func ReplyWith(w http.ResponseWriter, code int, bodyType string, msg []byte) {
156
h.Set("Content-Length", strconv.Itoa(len(msg)))
157
h.Set("Content-Type", bodyType)