use of writeJsonRespStructured is preferable. it api exists due to historical reason err.message is used as internal message for ApiError object in resp
(w http.ResponseWriter, err error, respBody interface{}, status int)
| 31 | // use of writeJsonRespStructured is preferable. it api exists due to historical reason |
| 32 | // err.message is used as internal message for ApiError object in resp |
| 33 | func WriteJsonResp(w http.ResponseWriter, err error, respBody interface{}, status int) { |
| 34 | response := Response{} |
| 35 | if err == nil { |
| 36 | response.Result = respBody |
| 37 | } else if apiErr, ok := err.(*util.ApiError); ok { |
| 38 | response.Errors = []*util.ApiError{apiErr} |
| 39 | if apiErr.HttpStatusCode != 0 { |
| 40 | status = apiErr.HttpStatusCode |
| 41 | } |
| 42 | } else if validationErrs, ok := err.(validator.ValidationErrors); ok { |
| 43 | var valErrors []*util.ApiError |
| 44 | for _, validationErr := range validationErrs { |
| 45 | //validationErr |
| 46 | valErr := &util.ApiError{ |
| 47 | UserMessage: fmt.Sprint(validationErr), |
| 48 | InternalMessage: fmt.Sprint(validationErr), |
| 49 | } |
| 50 | valErrors = append(valErrors, valErr) |
| 51 | } |
| 52 | response.Errors = valErrors |
| 53 | } else if util.IsErrNoRows(err) { |
| 54 | status = http.StatusNotFound |
| 55 | // Try to extract resource context from respBody for better error messages |
| 56 | resourceType, resourceId := extractResourceContext(respBody) |
| 57 | if resourceType != "" && resourceId != "" { |
| 58 | // Create context-aware resource not found error |
| 59 | apiErr := util.NewResourceNotFoundError(resourceType, resourceId) |
| 60 | response.Errors = []*util.ApiError{apiErr} |
| 61 | } else { |
| 62 | // Fallback to generic not found error (no more "pg: no rows in result set") |
| 63 | apiErr := util.NewGenericResourceNotFoundError() |
| 64 | response.Errors = []*util.ApiError{apiErr} |
| 65 | } |
| 66 | } else if util.IsResourceConflictError(err) { |
| 67 | // Handles response for error due to resource with the same identifier already exists. |
| 68 | status = http.StatusConflict |
| 69 | // Try to extract resource context from respBody for better error messages |
| 70 | resourceType, resourceId := extractResourceContext(respBody) |
| 71 | if resourceType != "" && resourceId != "" { |
| 72 | // Create context-aware resource duplicate error |
| 73 | apiErr := util.NewDuplicateResourceError(resourceType, resourceId) |
| 74 | response.Errors = []*util.ApiError{apiErr} |
| 75 | } else { |
| 76 | // Fallback to generic resource duplicate error |
| 77 | apiErr := util.NewGenericDuplicateResourceError() |
| 78 | response.Errors = []*util.ApiError{apiErr} |
| 79 | } |
| 80 | } else if multiErr, ok := err.(*multierror.Error); ok { |
| 81 | var errorsResp []*util.ApiError |
| 82 | for _, e := range multiErr.Errors { |
| 83 | errorResp := &util.ApiError{ |
| 84 | UserMessage: e.Error(), |
| 85 | InternalMessage: e.Error(), |
| 86 | } |
| 87 | errorsResp = append(errorsResp, errorResp) |
| 88 | } |
| 89 | response.Errors = errorsResp |
| 90 | } else if errStatus, ok := err.(*errors2.StatusError); ok { |
no test coverage detected
searching dependent graphs…