code.vegaprotocol.io/vega@v0.79.0/core/api/errors.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package api 17 18 import ( 19 types "code.vegaprotocol.io/vega/protos/vega" 20 21 "github.com/pkg/errors" 22 "google.golang.org/grpc/codes" 23 "google.golang.org/grpc/status" 24 ) 25 26 // API Errors and descriptions. 27 var ( 28 // ErrChainNotConnected signals to the user that he cannot access a given endpoint 29 // which require the chain, but the chain is actually offline. 30 ErrChainNotConnected = errors.New("chain not connected") 31 // ErrChannelClosed signals that the channel streaming data is closed. 32 ErrChannelClosed = errors.New("channel closed") 33 // ErrEmptyMissingMarketID signals to the caller that the request expected a 34 // market id but the field is missing or empty. 35 ErrEmptyMissingMarketID = errors.New("empty or missing market ID") 36 // ErrEmptyMissingOrderID signals to the caller that the request expected an 37 // order id but the field is missing or empty. 38 ErrEmptyMissingOrderID = errors.New("empty or missing order ID") 39 // ErrEmptyMissingOrderReference signals to the caller that the request expected an 40 // order reference but the field is missing or empty. 41 ErrEmptyMissingOrderReference = errors.New("empty or missing order reference") 42 // ErrEmptyMissingPartyID signals to the caller that the request expected a 43 // party id but the field is missing or empty. 44 ErrEmptyMissingPartyID = errors.New("empty or missing party ID") 45 // ErrEmptyMissingSinceTimestamp signals to the caller that the request expected a 46 // timestamp but the field is missing or empty. 47 ErrEmptyMissingSinceTimestamp = errors.New("empty or missing since-timestamp") 48 // ErrServerShutdown signals to the client that the server is shutting down. 49 ErrServerShutdown = errors.New("server shutdown") 50 // ErrStreamClosed signals to the users that the grpc stream is closing. 51 ErrStreamClosed = errors.New("stream closed") 52 // ErrStreamInternal signals to the users that the grpc stream has an internal problem. 53 ErrStreamInternal = errors.New("internal stream failure") 54 // ErrNotMapped is when an error cannot be found in the current error map/lookup table. 55 ErrNotMapped = errors.New("error not found in error lookup table") 56 // ErrInvalidMarketID signals that the market ID does not exists. 57 ErrInvalidMarketID = errors.New("invalid market ID") 58 // ErrMissingOrder signals that the actual payload is expected to contains an order. 59 ErrMissingOrder = errors.New("missing order in request payload") 60 // ErrMissingPartyID signals that the payload is expected to contain a party id. 61 ErrMissingPartyID = errors.New("missing party id") 62 // ErrMalformedRequest signals that the request was malformed. 63 ErrMalformedRequest = errors.New("malformed request") 64 // ErrMissingAsset signals that an asset was required but not specified. 65 ErrMissingAsset = errors.New("missing asset") 66 // ErrSubmitOrder is returned when submitting an order fails for some reason. 67 ErrSubmitOrder = errors.New("submit order failure") 68 // ErrAmendOrder is returned when amending an order fails for some reason. 69 ErrAmendOrder = errors.New("amend order failure") 70 // ErrCancelOrder is returned when cancelling an order fails for some reason. 71 ErrCancelOrder = errors.New("cancel order failure") 72 // OrderService... 73 ErrOrderServiceGetByMarket = errors.New("failed to get orders for market") 74 ErrOrderServiceGetByMarketAndID = errors.New("failed to get orders for market and ID") 75 ErrOrderServiceGetByParty = errors.New("failed to get orders for party") 76 ErrOrderServiceGetByReference = errors.New("failed to get orders for reference") 77 ErrMissingOrderIDParameter = errors.New("missing orderID parameter") 78 ErrOrderNotFound = errors.New("order not found") 79 // TradeService... 80 ErrTradeServiceGetByParty = errors.New("failed to get trades for party") 81 ErrTradeServiceGetByMarket = errors.New("failed to get trades for market") 82 ErrTradeServiceGetPositionsByParty = errors.New("failed to get positions for party") 83 ErrTradeServiceGetByOrderID = errors.New("failed to get trades for order ID") 84 // MarketService... 85 ErrMarketServiceGetMarkets = errors.New("failed to get markets") 86 ErrMarketServiceGetByID = errors.New("failed to get market for ID") 87 ErrMarketServiceGetDepth = errors.New("failed to get market depth") 88 ErrMarketServiceGetMarketData = errors.New("failed to get market data") 89 // AccountService... 90 ErrAccountServiceGetMarketAccounts = errors.New("failed to get market accounts") 91 // AccountService... 92 ErrAccountServiceGetFeeInfrastructureAccounts = errors.New("failed to get fee infrastructure accounts") 93 ErrAccountServiceGetPartyAccounts = errors.New("failed to get party accounts") 94 // RiskService... 95 ErrRiskServiceGetMarginLevelsByID = errors.New("failed to get margin levels") 96 // CandleService... 97 ErrCandleServiceGetCandles = errors.New("failed to get candles") 98 // PartyService... 99 ErrPartyServiceGetAll = errors.New("failed to get parties") 100 ErrPartyServiceGetByID = errors.New("failed to get party for ID") 101 // TimeService... 102 ErrTimeServiceGetTimeNow = errors.New("failed to get time now") 103 // Blockchain... 104 ErrBlockchainBacklogLength = errors.New("failed to get backlog length from blockchain") 105 ErrBlockchainNetworkInfo = errors.New("failed to get network info from blockchain") 106 ErrBlockchainGenesisTime = errors.New("failed to get genesis time from blockchain") 107 ErrBlockchainChainID = errors.New("failed to get chain ID from blockchain") 108 // ErrMissingProposalID returned if proposal with this id is missing. 109 ErrMissingProposalID = errors.New("missing proposal id") 110 // ErrMissingProposalReference returned if proposal with this reference is not found. 111 ErrMissingProposalReference = errors.New("failed to find proposal with the reference") 112 // ErrMissingWithdrawalID is returned when the ID is missing from the request. 113 ErrMissingWithdrawalID = errors.New("missing withdrawal ID") 114 // ErrMissingOracleSpecID is returned when the ID is missing from the request. 115 ErrMissingOracleSpecID = errors.New("missing oracle spec ID") 116 // ErrMissingDepositID is returned when the ID is missing from the request. 117 ErrMissingDepositID = errors.New("missing deposit ID") 118 ) 119 120 // errorMap contains a mapping between errors and Vega numeric error codes. 121 var errorMap = map[string]int32{ 122 // General 123 ErrNotMapped.Error(): 10000, 124 ErrChainNotConnected.Error(): 10001, 125 ErrChannelClosed.Error(): 10002, 126 ErrEmptyMissingMarketID.Error(): 10003, 127 ErrEmptyMissingOrderID.Error(): 10004, 128 ErrEmptyMissingOrderReference.Error(): 10005, 129 ErrEmptyMissingPartyID.Error(): 10006, 130 ErrEmptyMissingSinceTimestamp.Error(): 10007, 131 ErrStreamClosed.Error(): 10008, 132 ErrServerShutdown.Error(): 10009, 133 ErrStreamInternal.Error(): 10010, 134 ErrInvalidMarketID.Error(): 10011, 135 ErrMissingOrder.Error(): 10012, 136 ErrMissingPartyID.Error(): 10014, 137 ErrMalformedRequest.Error(): 10015, 138 ErrMissingAsset.Error(): 10017, 139 ErrSubmitOrder.Error(): 10018, 140 ErrAmendOrder.Error(): 10019, 141 ErrCancelOrder.Error(): 10020, 142 // Orders 143 ErrOrderServiceGetByMarket.Error(): 20001, 144 ErrOrderServiceGetByMarketAndID.Error(): 20002, 145 ErrOrderServiceGetByParty.Error(): 20003, 146 ErrOrderServiceGetByReference.Error(): 20004, 147 // Markets 148 ErrMarketServiceGetMarkets.Error(): 30001, 149 ErrMarketServiceGetByID.Error(): 30002, 150 ErrMarketServiceGetDepth.Error(): 30003, 151 ErrMarketServiceGetMarketData.Error(): 30004, 152 // Trades 153 ErrTradeServiceGetByMarket.Error(): 40001, 154 ErrTradeServiceGetByParty.Error(): 40002, 155 ErrTradeServiceGetPositionsByParty.Error(): 40003, 156 ErrTradeServiceGetByOrderID.Error(): 40004, 157 // Parties 158 ErrPartyServiceGetAll.Error(): 50001, 159 ErrPartyServiceGetByID.Error(): 50002, 160 // Candles 161 ErrCandleServiceGetCandles.Error(): 60001, 162 // Risk 163 ErrRiskServiceGetMarginLevelsByID.Error(): 70001, 164 // Accounts 165 ErrAccountServiceGetMarketAccounts.Error(): 80001, 166 ErrAccountServiceGetPartyAccounts.Error(): 80002, 167 ErrMissingWithdrawalID.Error(): 80003, 168 ErrMissingDepositID.Error(): 80004, 169 // Blockchain client 170 ErrBlockchainBacklogLength.Error(): 90001, 171 ErrBlockchainNetworkInfo.Error(): 90002, 172 ErrBlockchainGenesisTime.Error(): 90003, 173 // End of mapping 174 } 175 176 // ErrorMap returns a map of error to code, which is a mapping between 177 // API errors and Vega API specific numeric codes. 178 func ErrorMap() map[string]int32 { 179 return errorMap 180 } 181 182 // apiError is a helper function to build the Vega specific Error Details that 183 // can be returned by gRPC API and therefore also REST, GraphQL will be mapped too. 184 // It takes a standardised grpcCode, a Vega specific apiError, and optionally one 185 // or more internal errors (error from the core, rather than API). 186 func apiError(grpcCode codes.Code, apiError error, innerErrors ...error) error { 187 s := status.Newf(grpcCode, "%v error", grpcCode) 188 // Create the API specific error detail for error e.g. missing party ID 189 detail := types.ErrorDetail{ 190 Message: apiError.Error(), 191 } 192 // Lookup the API specific error in the table, return not found/not mapped 193 // if a code has not yet been added to the map, can happen if developer misses 194 // a step, periodic checking/ownership of API package can keep this up to date. 195 vegaCode, found := errorMap[apiError.Error()] 196 if found { 197 detail.Code = vegaCode 198 } else { 199 detail.Code = errorMap[ErrNotMapped.Error()] 200 } 201 // If there is an inner error (and possibly in the future, a config to turn this 202 // level of detail on/off) then process and append to inner. 203 first := true 204 for _, err := range innerErrors { 205 if !first { 206 detail.Inner += ", " 207 } 208 detail.Inner += err.Error() 209 first = false 210 } 211 // Pack the Vega domain specific errorDetails into the status returned by gRPC domain. 212 s, _ = s.WithDetails(&detail) 213 return s.Err() 214 }