(err error, w http.ResponseWriter, r *http.Request)
| 78 | } |
| 79 | |
| 80 | func HandleResponseError(err error, w http.ResponseWriter, r *http.Request) { |
| 81 | log := observability.GetLogEntry(r).Entry |
| 82 | errorID := utilities.GetRequestID(r.Context()) |
| 83 | |
| 84 | apiVersion, averr := DetermineClosestAPIVersion(r.Header.Get(APIVersionHeaderName)) |
| 85 | if averr != nil { |
| 86 | log.WithError(averr).Warn("Invalid version passed to " + APIVersionHeaderName + " header, defaulting to initial version") |
| 87 | } else if apiVersion != APIVersionInitial { |
| 88 | // Echo back the determined API version from the request |
| 89 | w.Header().Set(APIVersionHeaderName, FormatAPIVersion(apiVersion)) |
| 90 | } |
| 91 | |
| 92 | switch e := err.(type) { |
| 93 | case *WeakPasswordError: |
| 94 | if apiVersion.Compare(APIVersion20240101) >= 0 { |
| 95 | var output struct { |
| 96 | HTTPErrorResponse20240101 |
| 97 | Payload struct { |
| 98 | Reasons []string `json:"reasons,omitempty"` |
| 99 | } `json:"weak_password,omitempty"` |
| 100 | } |
| 101 | |
| 102 | output.Code = apierrors.ErrorCodeWeakPassword |
| 103 | output.Message = e.Message |
| 104 | output.Payload.Reasons = e.Reasons |
| 105 | |
| 106 | if jsonErr := sendJSON(w, http.StatusUnprocessableEntity, output); jsonErr != nil && jsonErr != context.DeadlineExceeded { |
| 107 | log.WithError(jsonErr).Warn("Failed to send JSON on ResponseWriter") |
| 108 | } |
| 109 | |
| 110 | } else { |
| 111 | var output struct { |
| 112 | HTTPError |
| 113 | Payload struct { |
| 114 | Reasons []string `json:"reasons,omitempty"` |
| 115 | } `json:"weak_password,omitempty"` |
| 116 | } |
| 117 | |
| 118 | output.HTTPStatus = http.StatusUnprocessableEntity |
| 119 | output.ErrorCode = apierrors.ErrorCodeWeakPassword |
| 120 | output.Message = e.Message |
| 121 | output.Payload.Reasons = e.Reasons |
| 122 | |
| 123 | w.Header().Set("x-sb-error-code", output.ErrorCode) |
| 124 | |
| 125 | if jsonErr := sendJSON(w, output.HTTPStatus, output); jsonErr != nil && jsonErr != context.DeadlineExceeded { |
| 126 | log.WithError(jsonErr).Warn("Failed to send JSON on ResponseWriter") |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | case *HTTPError: |
| 131 | switch { |
| 132 | case e.HTTPStatus >= http.StatusInternalServerError: |
| 133 | e.ErrorID = errorID |
| 134 | // this will get us the stack trace too |
| 135 | log.WithError(e.Cause()).Error(e.Error()) |
| 136 | case e.HTTPStatus == http.StatusTooManyRequests: |
| 137 | log.WithError(e.Cause()).Warn(e.Error()) |
searching dependent graphs…