github.com/cs3org/reva/v2@v2.27.7/internal/http/services/reqres/reqres.go (about)

     1  // Copyright 2018-2023 CERN
     2  //
     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
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     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 implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package reqres
    20  
    21  import (
    22  	"encoding/json"
    23  	"net/http"
    24  
    25  	"github.com/cs3org/reva/v2/pkg/appctx"
    26  )
    27  
    28  // APIErrorCode stores the type of error encountered.
    29  type APIErrorCode string
    30  
    31  // The various types of errors that can be expected to occur.
    32  const (
    33  	APIErrorNotFound         APIErrorCode = "RESOURCE_NOT_FOUND"
    34  	APIErrorUnauthenticated  APIErrorCode = "UNAUTHENTICATED"
    35  	APIErrorUntrustedService APIErrorCode = "UNTRUSTED_SERVICE"
    36  	APIErrorUnimplemented    APIErrorCode = "FUNCTION_NOT_IMPLEMENTED"
    37  	APIErrorInvalidParameter APIErrorCode = "INVALID_PARAMETER"
    38  	APIErrorProviderError    APIErrorCode = "PROVIDER_ERROR"
    39  	APIErrorAlreadyExist     APIErrorCode = "ALREADY_EXIST"
    40  	APIErrorServerError      APIErrorCode = "SERVER_ERROR"
    41  )
    42  
    43  // APIErrorCodeMapping stores the HTTP error code mapping for various APIErrorCodes.
    44  var APIErrorCodeMapping = map[APIErrorCode]int{
    45  	APIErrorNotFound:         http.StatusNotFound,
    46  	APIErrorUnauthenticated:  http.StatusUnauthorized,
    47  	APIErrorUntrustedService: http.StatusForbidden,
    48  	APIErrorUnimplemented:    http.StatusNotImplemented,
    49  	APIErrorInvalidParameter: http.StatusBadRequest,
    50  	APIErrorProviderError:    http.StatusBadGateway,
    51  	APIErrorAlreadyExist:     http.StatusConflict,
    52  	APIErrorServerError:      http.StatusInternalServerError,
    53  }
    54  
    55  // APIError encompasses the error type and message.
    56  type APIError struct {
    57  	Code    APIErrorCode `json:"code"`
    58  	Message string       `json:"message"`
    59  }
    60  
    61  // WriteError handles writing error responses.
    62  func WriteError(w http.ResponseWriter, r *http.Request, code APIErrorCode, message string, e error) {
    63  	if e != nil {
    64  		appctx.GetLogger(r.Context()).Error().Err(e).Msg(message)
    65  	}
    66  
    67  	var encoded []byte
    68  	var err error
    69  	w.Header().Set("Content-Type", "application/json")
    70  	encoded, err = json.MarshalIndent(APIError{Code: code, Message: message}, "", "  ")
    71  
    72  	if err != nil {
    73  		appctx.GetLogger(r.Context()).Error().Err(err).Msg("error encoding response")
    74  		w.WriteHeader(http.StatusInternalServerError)
    75  		return
    76  	}
    77  
    78  	w.WriteHeader(APIErrorCodeMapping[code])
    79  	_, err = w.Write(encoded)
    80  	if err != nil {
    81  		appctx.GetLogger(r.Context()).Error().Err(err).Msg("error writing response")
    82  		w.WriteHeader(http.StatusInternalServerError)
    83  	}
    84  }