Something went wrong. Try again.
forked from tailscale/tailscale
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152// 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}}