()
| 196 | } |
| 197 | |
| 198 | func (e *uploadError) Error() string { |
| 199 | switch e.StatusCode { |
| 200 | case http.StatusNotFound: |
| 201 | // The endpoint answers 404 rather than 403 when the token cannot write, |
| 202 | // so the status code alone points at the wrong problem. |
| 203 | return fmt.Sprintf("could not upload %s: attaching files requires write access to the repository", e.Path) |
| 204 | case http.StatusUnprocessableEntity: |
| 205 | if e.Message == "" { |
| 206 | return fmt.Sprintf("could not upload %s", e.Path) |
| 207 | } |
| 208 | return fmt.Sprintf("could not upload %s: %s", e.Path, strings.ReplaceAll(e.Message, "\n", "; ")) |
| 209 | case http.StatusTooManyRequests: |
| 210 | if e.RetryAfter == "" { |
| 211 | return fmt.Sprintf("could not upload %s: rate limited; wait and try again", e.Path) |
| 212 | } |
| 213 | retryAfter := e.RetryAfter |
| 214 | if seconds, err := strconv.Atoi(e.RetryAfter); err == nil { |
| 215 | retryAfter = fmt.Sprintf("%d seconds", seconds) |
| 216 | } |
| 217 | return fmt.Sprintf("could not upload %s: rate limited; retry after %s", e.Path, retryAfter) |
| 218 | } |
| 219 | return fmt.Sprintf("failed to upload %s: %v", e.Path, e.err) |
| 220 | } |
| 221 | |
| 222 | func (e *uploadError) Unwrap() error { |
| 223 | return e.err |
no outgoing calls