| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- // Copyright (c) Tailscale Inc & contributors
- // SPDX-License-Identifier: BSD-3-Clause
- package controlclient
- import (
- "errors"
- "fmt"
- "net/http"
- )
- // apiResponseError is an error type that can be returned by controlclient
- // api requests.
- //
- // It wraps an underlying error and a flag for clients to query if the
- // error is retryable via the Retryable() method.
- type apiResponseError struct {
- err error
- retryable bool
- }
- // Error implements [error].
- func (e *apiResponseError) Error() string {
- return e.err.Error()
- }
- // Retryable reports whether the error is retryable.
- func (e *apiResponseError) Retryable() bool {
- return e.retryable
- }
- func (e *apiResponseError) Unwrap() error { return e.err }
- var (
- errNoNodeKey = &apiResponseError{errors.New("no node key"), true}
- errNoNoiseClient = &apiResponseError{errors.New("no noise client"), true}
- errHTTPPostFailure = &apiResponseError{errors.New("http failure"), true}
- )
- func errBadHTTPResponse(code int, msg string) error {
- retryable := false
- switch code {
- case http.StatusTooManyRequests,
- http.StatusInternalServerError,
- http.StatusBadGateway,
- http.StatusServiceUnavailable,
- http.StatusGatewayTimeout:
- retryable = true
- }
- return &apiResponseError{fmt.Errorf("http error %d: %s", code, msg), retryable}
- }
|