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

     1  // Copyright 2018-2021 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 appprovider
    20  
    21  import (
    22  	"encoding/json"
    23  	"net/http"
    24  
    25  	"github.com/cs3org/reva/v2/pkg/appctx"
    26  )
    27  
    28  // appErrorCode stores the type of error encountered
    29  type appErrorCode string
    30  
    31  const (
    32  	appErrorNotFound         appErrorCode = "RESOURCE_NOT_FOUND"
    33  	appErrorAlreadyExists    appErrorCode = "RESOURCE_ALREADY_EXISTS"
    34  	appErrorUnauthenticated  appErrorCode = "UNAUTHENTICATED"
    35  	appErrorPermissionDenied appErrorCode = "PERMISSION_DENIED"
    36  	appErrorUnimplemented    appErrorCode = "NOT_IMPLEMENTED"
    37  	appErrorInvalidParameter appErrorCode = "INVALID_PARAMETER"
    38  	appErrorServerError      appErrorCode = "SERVER_ERROR"
    39  	appErrorTooEarly         appErrorCode = "TOO_EARLY"
    40  )
    41  
    42  // appErrorCodeMapping stores the HTTP error code mapping for various APIErrorCodes
    43  var appErrorCodeMapping = map[appErrorCode]int{
    44  	appErrorNotFound:         http.StatusNotFound,
    45  	appErrorAlreadyExists:    http.StatusForbidden,
    46  	appErrorUnauthenticated:  http.StatusUnauthorized,
    47  	appErrorUnimplemented:    http.StatusNotImplemented,
    48  	appErrorInvalidParameter: http.StatusBadRequest,
    49  	appErrorServerError:      http.StatusInternalServerError,
    50  	appErrorPermissionDenied: http.StatusForbidden,
    51  	appErrorTooEarly:         http.StatusTooEarly,
    52  }
    53  
    54  // APIError encompasses the error type and message
    55  type appError struct {
    56  	Code    appErrorCode `json:"code"`
    57  	Message string       `json:"message"`
    58  }
    59  
    60  // writeError handles writing error responses
    61  func writeError(w http.ResponseWriter, r *http.Request, code appErrorCode, message string, err error) {
    62  	if err != nil {
    63  		appctx.GetLogger(r.Context()).Error().Err(err).Msg(message)
    64  	}
    65  
    66  	var encoded []byte
    67  	w.Header().Set("Content-Type", "application/json")
    68  	encoded, err = json.MarshalIndent(appError{Code: code, Message: message}, "", "  ")
    69  
    70  	if err != nil {
    71  		appctx.GetLogger(r.Context()).Error().Err(err).Msg("error encoding response")
    72  		w.WriteHeader(http.StatusInternalServerError)
    73  		return
    74  	}
    75  
    76  	w.WriteHeader(appErrorCodeMapping[code])
    77  	_, err = w.Write(encoded)
    78  	if err != nil {
    79  		appctx.GetLogger(r.Context()).Error().Err(err).Msg("error writing response")
    80  		w.WriteHeader(http.StatusInternalServerError)
    81  	}
    82  }