github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/charmhub/transport/error.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package transport
     5  
     6  import (
     7  	"strings"
     8  )
     9  
    10  // APIError represents the error from the CharmHub API.
    11  type APIError struct {
    12  	Code    APIErrorCode  `json:"code"`
    13  	Message string        `json:"message"`
    14  	Extra   APIErrorExtra `json:"extra"`
    15  }
    16  
    17  func (a APIError) Error() string {
    18  	return a.Message
    19  }
    20  
    21  // APIErrors represents a slice of APIError's
    22  type APIErrors []APIError
    23  
    24  func (a APIErrors) Error() string {
    25  	if len(a) > 0 {
    26  		var combined []string
    27  		for _, e := range a {
    28  			if err := e.Error(); err != "" {
    29  				combined = append(combined, err)
    30  			}
    31  		}
    32  		return strings.Join(combined, "\n")
    33  	}
    34  	return ""
    35  }
    36  
    37  // APIErrorExtra defines additional extra payloads from a given error. Think
    38  // of this object as a series of suggestions to perform against the errorred
    39  // API request, in the chance of the new request being successful.
    40  type APIErrorExtra struct {
    41  	Releases     []Release `json:"releases"`
    42  	DefaultBases []Base    `json:"default-bases"`
    43  }
    44  
    45  // Release defines a set of suggested releases that might also work for the
    46  // given request.
    47  type Release struct {
    48  	Base    Base   `json:"base"`
    49  	Channel string `json:"channel"`
    50  }
    51  
    52  // APIErrorCode classifies the error code we get back from the API. This isn't
    53  // tautological list of codes.
    54  type APIErrorCode string
    55  
    56  const (
    57  	ErrorCodeAccessByDownstreamStoreNotAllowed APIErrorCode = "access-by-downstream-store-not-allowed"
    58  	ErrorCodeAccessByRevisionNotAllowed        APIErrorCode = "access-by-revision-not-allowed"
    59  	ErrorCodeAPIError                          APIErrorCode = "api-error"
    60  	ErrorCodeBadArgument                       APIErrorCode = "bad-argument"
    61  	ErrorCodeCharmResourceNotFound             APIErrorCode = "charm-resource-not-found"
    62  	ErrorCodeChannelNotFound                   APIErrorCode = "channel-not-found"
    63  	ErrorCodeDeviceAuthorizationNeedsRefresh   APIErrorCode = "device-authorization-needs-refresh"
    64  	ErrorCodeDeviceServiceDisallowed           APIErrorCode = "device-service-disallowed"
    65  	ErrorCodeDuplicatedKey                     APIErrorCode = "duplicated-key"
    66  	ErrorCodeDuplicateFetchAssertionsKey       APIErrorCode = "duplicate-fetch-assertions-key"
    67  	ErrorCodeEndpointDisabled                  APIErrorCode = "endpoint-disabled"
    68  	ErrorCodeIDNotFound                        APIErrorCode = "id-not-found"
    69  	ErrorCodeInconsistentData                  APIErrorCode = "inconsistent-data"
    70  	ErrorCodeInstanceKeyNotUnique              APIErrorCode = "instance-key-not-unique"
    71  	ErrorCodeInvalidChannel                    APIErrorCode = "invalid-channel"
    72  	ErrorCodeInvalidCharmBase                  APIErrorCode = "invalid-charm-base"
    73  	ErrorCodeInvalidCharmResource              APIErrorCode = "invalid-charm-resource"
    74  	ErrorCodeInvalidCohortKey                  APIErrorCode = "invalid-cohort-key"
    75  	ErrorCodeInvalidGrade                      APIErrorCode = "invalid-grade"
    76  	ErrorCodeInvalidMetric                     APIErrorCode = "invalid-metric"
    77  	ErrorCodeInvalidUnboundEmptySearch         APIErrorCode = "invalid-unbound-empty-search"
    78  	ErrorCodeMacaroonPermissionRequired        APIErrorCode = "macaroon-permission-required"
    79  	ErrorCodeMissingCharmBase                  APIErrorCode = "missing-charm-base"
    80  	ErrorCodeMissingContext                    APIErrorCode = "missing-context"
    81  	ErrorCodeMissingFetchAssertionsKey         APIErrorCode = "missing-fetch-assertions-key"
    82  	ErrorCodeMissingHeader                     APIErrorCode = "missing-header"
    83  	ErrorCodeMissingInstanceKey                APIErrorCode = "missing-instance-key"
    84  	ErrorCodeMissingKey                        APIErrorCode = "missing-key"
    85  	ErrorCodeNameNotFound                      APIErrorCode = "name-not-found"
    86  	ErrorCodeNotFound                          APIErrorCode = "not-found"
    87  	ErrorCodePaymentRequired                   APIErrorCode = "payment-required"
    88  	ErrorCodeRateLimitExceeded                 APIErrorCode = "rate-limit-exceeded"
    89  	ErrorCodeRefreshBundleNotSupported         APIErrorCode = "refresh-bundle-not-supported"
    90  	ErrorCodeRemoteServiceUnavailable          APIErrorCode = "remote-service-unavailable"
    91  	ErrorCodeResourceNotFound                  APIErrorCode = "resource-not-found"
    92  	ErrorCodeRevisionConflict                  APIErrorCode = "revision-conflict"
    93  	ErrorCodeRevisionNotFound                  APIErrorCode = "revision-not-found"
    94  	ErrorCodeServiceMisconfigured              APIErrorCode = "service-misconfigured"
    95  	ErrorCodeStoreAuthorizationNeedsRefresh    APIErrorCode = "store-authorization-needs-refresh"
    96  	ErrorCodeStoreDisallowed                   APIErrorCode = "store-disallowed"
    97  	ErrorCodeUnexpectedData                    APIErrorCode = "unexpected-data"
    98  	ErrorCodeUnknownGrade                      APIErrorCode = "unknown-grade"
    99  	ErrorCodeUserAuthenticationError           APIErrorCode = "user-authentication-error"
   100  	ErrorCodeUserAuthorizationNeedsRefresh     APIErrorCode = "user-authorization-needs-refresh"
   101  	// TODO 2021-04-08 hml
   102  	// Remove once Charmhub API returns ErrorCodeInvalidCharmBase
   103  	ErrorCodeInvalidCharmPlatform APIErrorCode = "invalid-charm-platform"
   104  	ErrorCodeMissingCharmPlatform APIErrorCode = "missing-charm-platform"
   105  )