diff --git a/pkg/service/binance/binance.go b/pkg/service/binance/binance.go index d717879ff..031edbc87 100644 --- a/pkg/service/binance/binance.go +++ b/pkg/service/binance/binance.go @@ -12,6 +12,7 @@ import ( "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/response" bapdater "github.com/defipod/mochi/pkg/service/binance/adapter" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -23,9 +24,10 @@ type Binance struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &Binance{ getExchangeInfoURL: "https://api.binance.com/api/v3/exchangeInfo", getSymbolKlinesURL: "https://api.binance.com/api/v3/uiKlines?symbol=%s&interval=1h&limit=168", // 168h = 7d @@ -34,9 +36,16 @@ func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service config: cfg, logger: l, cache: cache, + sentry: sentry, } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (b *Binance) GetExchangeInfo(symbol string) (*response.GetExchangeInfoResponse, error, int) { b.logger.Debug("start binance.GetExchangeInfo()") defer b.logger.Debug("end binance.GetExchangeInfo()") @@ -59,6 +68,13 @@ func (b *Binance) GetExchangeInfo(symbol string) (*response.GetExchangeInfoRespo statusCode, err := util.FetchData(url, res) if err != nil || statusCode != http.StatusOK { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetExchangeInfo failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "symbols": symbol, + }, + }) return nil, fmt.Errorf("binance.GetExchangeInfo() failed: %v", err), statusCode } @@ -93,6 +109,13 @@ func (b *Binance) GetTickerPrice(symbol string) (*response.GetTickerPriceRespons statusCode, err := util.FetchData(url, res) if err != nil || statusCode != http.StatusOK { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetTickerPrice failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "symbols": symbol, + }, + }) return nil, fmt.Errorf("binance.GetTickerPrice() failed: %v", err), statusCode } @@ -126,6 +149,13 @@ func (b *Binance) GetAvgPriceBySymbol(symbol string) (*response.GetAvgPriceBySym statusCode, err := util.FetchData(url, res) if err != nil || statusCode != http.StatusOK { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetAvgPriceBySymbol failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "symbols": symbol, + }, + }) return nil, fmt.Errorf("binance.GetAvgPriceBySymbol() failed: %v", err), statusCode } @@ -156,6 +186,13 @@ func (b *Binance) GetKlinesBySymbol(symbol string) ([]response.GetKlinesDataResp statusCode, err := util.FetchData(fmt.Sprintf(b.getSymbolKlinesURL, symbol), &data) if err != nil || statusCode != http.StatusOK { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetKlinesBySymbol failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "symbols": symbol, + }, + }) return nil, fmt.Errorf("binance.GetKlinesBySymbol() failed: %v", err), statusCode } @@ -201,6 +238,14 @@ func (b *Binance) GetUserAsset(apiKey, apiSecret string) ([]response.BinanceUser res, err = bapdater.GetUserAsset(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetUserAsset failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -229,6 +274,14 @@ func (b *Binance) GetFundingAsset(apiKey, apiSecret string) ([]response.BinanceU res, err = bapdater.GetFundingAsset(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetFundingAsset failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -257,6 +310,14 @@ func (b *Binance) GetStakingProductPosition(apiKey, apiSecret string) ([]respons res, err = bapdater.GetStakingProductPosition(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetStakingProductPosition failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -285,6 +346,14 @@ func (b *Binance) GetLendingAccount(apiKey, apiSecret string) (*response.Binance res, err = bapdater.GetLendingAccount(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetLendingAccount failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -313,6 +382,14 @@ func (b *Binance) GetSimpleEarn(apiKey, apiSecret string) (*response.BinanceSimp res, err = bapdater.GetSimpleEarnAccount(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetSimpleEarn failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -341,6 +418,14 @@ func (b *Binance) GetFutureAccountBalance(apiKey, apiSecret string) ([]response. res, err = bapdater.GetFutureAccountBalance(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetFutureAccountBinance failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -369,6 +454,14 @@ func (b *Binance) GetFutureAccount(apiKey, apiSecret string) (*response.BinanceF res, err = bapdater.GetFutureAccount(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetFutureAccount failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } @@ -397,6 +490,14 @@ func (b *Binance) GetFutureAccountInfo(apiKey, apiSecret string) ([]response.Bin res, err = bapdater.GetFutureAccountInfo(apiKey, apiSecret) if err != nil { + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Binance - GetFutureAccountInfo failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "apiKey": apiKey, + "apiSecret": apiSecret, + }, + }) return nil, err } diff --git a/pkg/service/birdeye/birdeye.go b/pkg/service/birdeye/birdeye.go index 14bbb0def..7470bd0f3 100644 --- a/pkg/service/birdeye/birdeye.go +++ b/pkg/service/birdeye/birdeye.go @@ -10,6 +10,7 @@ import ( "github.com/defipod/mochi/pkg/cache" "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -17,19 +18,24 @@ type birdeye struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &birdeye{ config: cfg, logger: l, cache: cache, + sentry: sentry, } } var ( publicBirdeye = "https://public-api.birdeye.so" birdeyeTokenPriceKey = "birdeye-token-price" + sentryTags = map[string]string{ + "type": "system", + } ) func (b *birdeye) GetTokenPrice(address string) (*TokenPrice, error) { @@ -75,6 +81,13 @@ func (b *birdeye) doNetworkTokenPrice(address string) (*TokenPrice, error) { err := b.fetchBirdeyeData(url, &res) if err != nil { b.logger.Fields(logger.Fields{"url": url}).Error(err, "[birdeye.GetTokenPrice] b.fetchBirdeyeData() failed") + b.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Birdeye - doNetWorkTokenPrice failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, err } diff --git a/pkg/service/chainexplorer/chainexplorer.go b/pkg/service/chainexplorer/chainexplorer.go index 432d4c352..ea3cba210 100644 --- a/pkg/service/chainexplorer/chainexplorer.go +++ b/pkg/service/chainexplorer/chainexplorer.go @@ -11,23 +11,32 @@ import ( "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/model" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) type chainExplorer struct { - cfg config.Config - log logger.Logger - cache cache.Cache + cfg config.Config + log logger.Logger + cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg config.Config, log logger.Logger, cache cache.Cache) Service { +func NewService(cfg config.Config, log logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &chainExplorer{ - cfg: cfg, - log: log, - cache: cache, + cfg: cfg, + log: log, + cache: cache, + sentry: sentry, } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (c *chainExplorer) GetGasTracker(listChain []model.Chain) ([]response.GasTrackerResponse, error) { apiKey := "" gasTrackerResp := make([]response.GasTrackerResponse, 0) @@ -92,6 +101,13 @@ func (c *chainExplorer) doNetworkGetGasTracker(url string, resp interface{}) err } statusCode, err := util.SendRequest(query) if err != nil { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - ChainExplorer - doNetWorkGetGasTracker failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return fmt.Errorf("send request failed: %v", err) } diff --git a/pkg/service/coingecko/adapter.go b/pkg/service/coingecko/adapter.go index 7be8dcbaf..fec6e19c2 100644 --- a/pkg/service/coingecko/adapter.go +++ b/pkg/service/coingecko/adapter.go @@ -9,6 +9,7 @@ import ( "time" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -27,6 +28,15 @@ func (c *CoinGecko) doNetworkCoinByContract(platformId, contractAddress string, } if err != nil || status != http.StatusOK { if retry == 0 { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - doNetworkCoinByContract failed - %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "platformId": platformId, + "contractAddress": contractAddress, + "retry": retry, + }, + }) return nil, fmt.Errorf("%d - %v", status, err) } else { return c.GetCoinByContract(platformId, contractAddress, retry-1) diff --git a/pkg/service/coingecko/coingecko.go b/pkg/service/coingecko/coingecko.go index 666a3913d..959138cf4 100644 --- a/pkg/service/coingecko/coingecko.go +++ b/pkg/service/coingecko/coingecko.go @@ -12,6 +12,7 @@ import ( errs "github.com/defipod/mochi/pkg/model/errors" "github.com/defipod/mochi/pkg/request" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -31,9 +32,10 @@ type CoinGecko struct { geckoTerminalSearchURL string getGlobalCryptoDataURL string cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, cache cache.Cache) Service { +func NewService(cfg *config.Config, cache cache.Cache, sentry sentrygo.Service) Service { apiKey := cfg.CoinGeckoAPIKey return &CoinGecko{ @@ -52,11 +54,15 @@ func NewService(cfg *config.Config, cache cache.Cache) Service { getGlobalCryptoDataURL: "https://pro-api.coingecko.com/api/v3/global?x_cg_pro_api_key=" + apiKey, geckoTerminalSearchURL: "https://app.geckoterminal.com/api/p1/search", cache: cache, + sentry: sentry, } } var ( coingeckoGetTokenByContractKey = "coingecko-token-contract-key" + sentryTags = map[string]string{ + "type": "system", + } ) func (c *CoinGecko) GetHistoricalMarketData(coinID, currency string, days int) (*response.HistoricalMarketChartResponse, error, int) { @@ -72,6 +78,13 @@ func (c *CoinGecko) GetCoin(coinID string) (*response.GetCoinResponse, error, in data := &response.GetCoinResponse{} statusCode, err := util.FetchData(fmt.Sprintf(c.getCoinURL, coinID), data) if err != nil || statusCode != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetCoin failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "coinID": coinID, + }, + }) return nil, fmt.Errorf("failed to fetch coin data of %s: %v", coinID, err), statusCode } @@ -96,6 +109,13 @@ func (c *CoinGecko) GetCoinPrice(coinIDs []string, currency string) (map[string] if coinIDsArg != "" { statusCode, err := util.FetchData(fmt.Sprintf(c.getPriceURL, coinIDsArg, currency), resp) if err != nil || statusCode != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetCoinPrice failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "coinIDs": coinIDs, + }, + }) return prices, fmt.Errorf("failed to fetch price data of %s: %v", coinIDs, err) } } @@ -119,6 +139,14 @@ func (c *CoinGecko) GetHistoryCoinInfo(sourceSymbol string, days string) (resp [ if statusCode == http.StatusNotFound { return nil, errs.ErrRecordNotFound, statusCode } + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetHistoryCoinInfo failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "sourceSymbol": sourceSymbol, + "days": days, + }, + }) return nil, err, statusCode } @@ -131,6 +159,16 @@ func (c *CoinGecko) GetCoinsMarketData(ids []string, sparkline bool, page, pageS statusCode, err := util.FetchData(fmt.Sprintf(c.getCoinsMarketData, strings.Join(ids, ","), pageSize, page, sparkline), &resTmp) if err != nil { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetCoinsMarketData failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "ids": ids, + "page": page, + "pageSize": pageSize, + "sparkline": sparkline, + }, + }) return nil, err, statusCode } @@ -145,6 +183,10 @@ func (c *CoinGecko) GetSupportedCoins() ([]response.CoingeckoSupportedTokenRespo data := make([]response.CoingeckoSupportedTokenResponse, 0) statusCode, err := util.FetchData(c.getSupportedCoins, &data) if err != nil || statusCode != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetSupportedCoins failed %v", err), + Tags: sentryTags, + }) return nil, fmt.Errorf("failed to fetch supported coins list: %v", err), statusCode } return data, nil, http.StatusOK @@ -154,6 +196,10 @@ func (c *CoinGecko) GetAssetPlatforms() ([]*response.AssetPlatformResponseData, var res []*response.AssetPlatformResponseData status, err := util.FetchData(c.getAssetPlatforms, &res) if err != nil || status != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetAssetPlatforms failed %v", err), + Tags: sentryTags, + }) return nil, fmt.Errorf("failed to fetch asset platforms with status %d: %v", status, err) } return res, nil @@ -176,6 +222,10 @@ func (c *CoinGecko) GetTrendingSearch() (*response.GetTrendingSearch, error) { var res response.GetTrendingSearch status, err := util.FetchData(c.getTrendingSearch, &res) if err != nil || status != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetTrendingSearch failed %v", err), + Tags: sentryTags, + }) return nil, fmt.Errorf("failed to fetch trending search with status %d: %v", status, err) } return &res, nil @@ -189,6 +239,10 @@ func (c *CoinGecko) GetTopLoserGainer(req request.TopGainerLoserRequest) (*respo if status == http.StatusBadRequest { return nil, errs.ErrInvalidCoingeckoSvcParam } + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetTopLoserGainer failed %v", err), + Tags: sentryTags, + }) return nil, fmt.Errorf("failed to fetch trending search with status %d: %v", status, err) } return &res, nil @@ -199,6 +253,13 @@ func (c *CoinGecko) GetHistoricalGlobalMarketChart(days int) (*response.GetHisto url := fmt.Sprintf(c.getHistoricalGlobalMarketChartURL, days) status, err := util.FetchData(url, &res) if err != nil { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetHistoricalGlobalMarketChart failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "days": days, + }, + }) return nil, fmt.Errorf("failed to fetch global market chart with status %d: %v", status, err) } return res, nil @@ -209,6 +270,10 @@ func (c *CoinGecko) GetGlobalData() (*response.GetGlobalDataResponse, error) { url := c.getGlobalCryptoDataURL status, err := util.FetchData(url, &res) if err != nil { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - GetTopLoserGainer failed %v", err), + Tags: sentryTags, + }) return nil, fmt.Errorf("failed to fetch global market chart with status %d: %v", status, err) } return res, nil @@ -228,6 +293,13 @@ func (c *CoinGecko) SearchCoin(query string) (*response.SearchCoinResponse, erro statusCode, err := util.FetchData(req.URL.String(), resp) if err != nil || statusCode != http.StatusOK { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Coingecko - SearchCoin failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "query": query, + }, + }) return nil, fmt.Errorf("failed to search coin %s: %v", query, err), statusCode } diff --git a/pkg/service/covalent/adapter.go b/pkg/service/covalent/adapter.go index 137620099..4d69d6015 100644 --- a/pkg/service/covalent/adapter.go +++ b/pkg/service/covalent/adapter.go @@ -9,6 +9,7 @@ import ( "time" "github.com/defipod/mochi/pkg/logger" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -22,10 +23,28 @@ func (c *Covalent) doNetworkSolanaTokenBalances(chainName string, address string code, err := c.fetchCovalentData(endpoint, res) if err != nil { c.logger.Fields(logger.Fields{"endpoint": endpoint, "code": code}).Error(err, "[covalent.chainName] util.FetchData() failed") + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - doNetworkTokenBalances failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainName": chainName, + "address": address, + "retry": retry, + }, + }) return nil, err } if res.Error { if retry == 0 { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - doNetworkTokenBalances failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainName": chainName, + "address": address, + "retry": retry, + }, + }) return nil, fmt.Errorf("%d - %s", res.ErrorCode, res.ErrorMessage) } else { return c.GetSolanaTokenBalances(chainName, address, retry-1) @@ -59,6 +78,16 @@ func (c *Covalent) doNetworkTransaction(chainID int, address string, size int, r } if res.Error { if retry == 0 { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - doNetworkTransaction failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "size": size, + "retry": retry, + }, + }) return nil, fmt.Errorf("%d - %s", res.ErrorCode, res.ErrorMessage) } else { return c.GetTransactionsByAddress(chainID, address, size, retry-1) @@ -79,6 +108,15 @@ func (c *Covalent) doNetworkTokenBalances(chainID int, address string, retry int res := &GetTokenBalancesResponse{} code, err := c.fetchCovalentData(endpoint, res) if err != nil { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - doNetworkTokenBalances failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "retry": retry, + }, + }) c.logger.Fields(logger.Fields{"endpoint": endpoint, "code": code}).Error(err, "[covalent.GetTokenBalances] util.FetchData() failed") return nil, err } @@ -90,6 +128,15 @@ func (c *Covalent) doNetworkTokenBalances(chainID int, address string, retry int } if retry == 0 { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - doNetworkTokenBalances failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "retry": retry, + }, + }) return nil, fmt.Errorf("%d - %s", res.ErrorCode, res.ErrorMessage) } else { return c.GetTokenBalances(chainID, address, retry-1) diff --git a/pkg/service/covalent/covalent.go b/pkg/service/covalent/covalent.go index 75dce9e00..c02d00762 100644 --- a/pkg/service/covalent/covalent.go +++ b/pkg/service/covalent/covalent.go @@ -10,6 +10,7 @@ import ( "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" ) var networks = map[int]string{ @@ -32,16 +33,24 @@ type Covalent struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &Covalent{ config: cfg, logger: l, cache: cache, + sentry: sentry, } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (c *Covalent) getFullUrl(endpoint string, idx int) string { url := c.config.CovalentBaseUrl + endpoint if strings.Contains(url, "?") { @@ -62,6 +71,15 @@ func (c *Covalent) GetHistoricalTokenPrices(chainID int, currency string, addres code, err := c.fetchCovalentData(endpoint, res) if err != nil || code != http.StatusOK { c.logger.Fields(logger.Fields{"endpoint": endpoint, "code": code}).Error(err, "[covalent.GetTransactionsByAddress] util.FetchData() failed") + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - GetHistoricalTokenPrices failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "currency": currency, + }, + }) return nil, fmt.Errorf("failed to fetch token data of %s: %v", currency, err), code } return res, nil, http.StatusOK @@ -92,10 +110,30 @@ func (c *Covalent) GetTransactionsByAddressV3(chainID int, address string, size code, err := c.fetchCovalentData(endpoint, res) if err != nil { c.logger.Fields(logger.Fields{"endpoint": endpoint, "code": code}).Error(err, "[covalent.GetTransactionsByAddress] util.FetchData() failed") + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - GetTransactionsByAddressV3 failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "size": size, + "retry": retry, + }, + }) return nil, err } if res.Error { if retry == 0 { + c.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Covalent - GetTransactionsByAddressV3 failed %v", res.Error), + Tags: sentryTags, + Extra: map[string]interface{}{ + "chainID": chainID, + "address": address, + "size": size, + "retry": retry, + }, + }) return nil, fmt.Errorf("%d - %s", res.ErrorCode, res.ErrorMessage) } else { return c.GetTransactionsByAddress(chainID, address, size, retry-1) diff --git a/pkg/service/dexscreener/dexscreener.go b/pkg/service/dexscreener/dexscreener.go index ee58b8fc8..d8260cfea 100644 --- a/pkg/service/dexscreener/dexscreener.go +++ b/pkg/service/dexscreener/dexscreener.go @@ -3,6 +3,7 @@ package dexscreener import ( "fmt" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -11,21 +12,44 @@ const ( ) type dexscreener struct { + sentry sentrygo.Service } -func NewService() Service { - return &dexscreener{} +func NewService(sentry sentrygo.Service) Service { + return &dexscreener{ + sentry: sentry, + } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (d *dexscreener) Search(query string) ([]Pair, error) { pairResponse := PairResponse{} url := fmt.Sprintf("%s/search?q=%s", baseUrl, query) status, err := util.FetchData(url, &pairResponse) if err != nil { + d.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - DexScreener - Search failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "query": query, + }, + }) return nil, fmt.Errorf("failed to fetch data from dexscreener: %w", err) } if status != 200 { + d.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - DexScreener - Search failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "query": query, + }, + }) return nil, fmt.Errorf("failed to fetch data from dexscreener, status: %d", status) } @@ -37,10 +61,26 @@ func (d *dexscreener) Get(network, address string) (*Pair, error) { url := fmt.Sprintf("%s/pairs/%s/%s", baseUrl, network, address) status, err := util.FetchData(url, &pairResponse) if err != nil { + d.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - DexScreener - Get failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "network": network, + "address": address, + }, + }) return nil, fmt.Errorf("failed to fetch data from dexscreener: %w", err) } if status != 200 { + d.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - DexScreener - Get failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "network": network, + "address": address, + }, + }) return nil, fmt.Errorf("failed to fetch data from dexscreener, status: %d", status) } diff --git a/pkg/service/ethplorer/ethplorer.go b/pkg/service/ethplorer/ethplorer.go index cb533f3fd..8a40a0392 100644 --- a/pkg/service/ethplorer/ethplorer.go +++ b/pkg/service/ethplorer/ethplorer.go @@ -3,6 +3,7 @@ package ethplorer import ( "fmt" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -12,12 +13,21 @@ const ( ) type ethplorer struct { + sentry sentrygo.Service } -func NewService() Service { - return ðplorer{} +func NewService(sentry sentrygo.Service) Service { + return ðplorer{ + sentry: sentry, + } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (e *ethplorer) GetTopTokenHolders(address string, limit int) (*TokenHoldersResponse, error) { resp := &TokenHoldersResponse{} @@ -25,10 +35,24 @@ func (e *ethplorer) GetTopTokenHolders(address string, limit int) (*TokenHolders status, err := util.FetchData(url, resp) if err != nil { + e.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - EthExplorer - GetTopTokenHolders failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, fmt.Errorf("fetch data failed: %w", err) } if status != 200 { + e.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - EthExplorer - GetTopTokenHolders failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, fmt.Errorf("fetch data failed: status %d", status) } @@ -42,10 +66,24 @@ func (e *ethplorer) GetTokenInfo(address string) (*TokenInfoResponse, error) { status, err := util.FetchData(url, resp) if err != nil { + e.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - EthExplorer - GetTopTokenHolders failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, fmt.Errorf("fetch data failed: %w", err) } if status != 200 { + e.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - EthExplorer - GetTopTokenHolders failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, fmt.Errorf("fetch data failed: status %d", status) } diff --git a/pkg/service/friendtech/friend_tech.go b/pkg/service/friendtech/friend_tech.go index 21282cb00..05c2fd6ee 100644 --- a/pkg/service/friendtech/friend_tech.go +++ b/pkg/service/friendtech/friend_tech.go @@ -8,11 +8,13 @@ import ( "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/consts" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) type FriendTech struct { baseUrl string + sentry sentrygo.Service } var commonHeader = map[string]string{ @@ -22,7 +24,7 @@ var commonHeader = map[string]string{ "x-client-id": consts.ClientID, } -func NewService(cfg *config.Config) Service { +func NewService(cfg *config.Config, sentry sentrygo.Service) Service { baseUrl := cfg.FriendScanAPI if baseUrl == "" { baseUrl = "https://api.friendscan.tech" @@ -33,6 +35,12 @@ func NewService(cfg *config.Config) Service { } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (n *FriendTech) Search(query string, limit int) (*response.FriendTechKeysResponse, error) { if limit == 0 || limit > 200 { limit = 200 @@ -47,6 +55,13 @@ func (n *FriendTech) Search(query string, limit int) (*response.FriendTechKeysRe } statusCode, err := util.SendRequest(req) if err != nil || statusCode != http.StatusOK { + n.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - FriendTech - Search failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return &response.FriendTechKeysResponse{}, nil } return &data, nil @@ -63,6 +78,13 @@ func (n *FriendTech) GetHistory(accountAddress, interval string) (*response.Frie statusCode, err := util.SendRequest(req) if err != nil || statusCode != http.StatusOK { + n.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - FriendTech - GetHistory failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return &response.FriendTechKeyPriceHistoryResponse{}, nil } @@ -83,10 +105,24 @@ func (n *FriendTech) GetTransactions(subjectAddress string, limit int) (*respons } statusCode, err := util.SendRequest(req) if err != nil { + n.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - FriendTech - GetTransaction failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return &response.FriendTechKeyTransactionsResponse{}, err } if statusCode != http.StatusOK { + n.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - FriendTech - GetTransaction failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return &response.FriendTechKeyTransactionsResponse{}, errors.New("fetch status code is not 200") } diff --git a/pkg/service/krystal/krystal.go b/pkg/service/krystal/krystal.go index bf09a18bf..9353baf9f 100644 --- a/pkg/service/krystal/krystal.go +++ b/pkg/service/krystal/krystal.go @@ -11,6 +11,7 @@ import ( "github.com/defipod/mochi/pkg/cache" "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -18,16 +19,24 @@ type Krystal struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &Krystal{ config: cfg, logger: l, cache: cache, + sentry: sentry, } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + const ( tokenBalanceKey = "krystal-balance-token" ) @@ -113,6 +122,13 @@ func (k *Krystal) doNetwork(address string, data BalanceTokenResponse) (*Balance statusCode, err := util.SendRequest(req) if err != nil { + k.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Krystal - doNetWork failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "url": url, + }, + }) return nil, fmt.Errorf("[krystal.GetBalanceTokenByAddress] util.SendRequest() failed: %v", err) } @@ -139,6 +155,13 @@ func (k *Krystal) doNetworkGeneric(req util.SendRequestQuery, response interface if statusCode != http.StatusOK { err = fmt.Errorf("krystal.doNetworkGeneric() failed, status code: %d", statusCode) k.logger.Error(err, "krystal.doNetworkGeneric() failed") + k.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Krystal - doNetWorkGeneric failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "req": req, + }, + }) return err } @@ -173,6 +196,13 @@ func (k *Krystal) buildTx(path string, req interface{}) (*BuildTxResp, error) { ParseForm: res, }) if err != nil { + k.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Krystal - buildTx failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "req": req, + }, + }) return nil, err } if status != http.StatusOK { diff --git a/pkg/service/nghenhan/nghenhan.go b/pkg/service/nghenhan/nghenhan.go index ea0636add..42d1a7fe6 100644 --- a/pkg/service/nghenhan/nghenhan.go +++ b/pkg/service/nghenhan/nghenhan.go @@ -5,19 +5,27 @@ import ( "net/http" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) type Nghenhan struct { baseUrl string + sentry sentrygo.Service } -func NewService() Service { +func NewService(sentry sentrygo.Service) Service { return &Nghenhan{ baseUrl: "https://cex.console.so/api/v1", } } +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (n *Nghenhan) GetFiatHistoricalChart(base, target, interval string, limit int) (*response.NghenhanFiatHistoricalChartResponse, error) { tmpBase := base tmpTarg := target @@ -30,6 +38,16 @@ func (n *Nghenhan) GetFiatHistoricalChart(base, target, interval string, limit i } statusCode, err := util.SendRequest(req) if err != nil || statusCode != http.StatusOK { + n.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Nghenhan - GetFiatHistoricalChart failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "base": base, + "target": target, + "interval": interval, + "limit": limit, + }, + }) return &response.NghenhanFiatHistoricalChartResponse{ Data: []response.NghenhanFiatHistoricalChart{}, }, nil diff --git a/pkg/service/service.go b/pkg/service/service.go index 7d282bc64..403659232 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -95,33 +95,35 @@ func NewService( log.Error(err, "failed to init ronin svc") } + sentry := sentrygo.New(&cfg, log) + return &Service{ - CoinGecko: coingecko.NewService(&cfg, cache), - Covalent: covalent.NewService(&cfg, log, cache), + CoinGecko: coingecko.NewService(&cfg, cache, sentry), + Covalent: covalent.NewService(&cfg, log, cache, sentry), Discord: discordSvc, Indexer: indexer.NewIndexer(cfg, log), Abi: abi.NewAbi(&cfg), Cloud: cloud.NewCloudClient(&cfg, log), - Nghenhan: nghenhan.NewService(), + Nghenhan: nghenhan.NewService(sentry), Processor: processor.NewProcessor(&cfg), - Solscan: solscan.NewService(&cfg, log, cache), - Binance: binance.NewService(&cfg, log, cache), + Solscan: solscan.NewService(&cfg, log, cache, sentry), + Binance: binance.NewService(&cfg, log, cache, sentry), APILayer: apilayer.NewService(&cfg), Bluemove: bluemove.New(&cfg, log), MochiProfile: mochiprofile.NewService(&cfg, log), MochiPay: mochipay.NewService(&cfg, log), - ChainExplorer: chainexplorer.NewService(cfg, log, cache), - Sui: sui.New(&cfg, log, cache), - Birdeye: birdeye.NewService(&cfg, log, cache), + ChainExplorer: chainexplorer.NewService(cfg, log, cache, sentry), + Sui: sui.New(&cfg, log, cache, sentry), + Birdeye: birdeye.NewService(&cfg, log, cache, sentry), Swap: swap.New(&cfg, log), - Skymavis: skymavis.New(&cfg, cache), + Skymavis: skymavis.New(&cfg, cache, sentry), Ronin: roninSvc, - Krystal: krystal.NewService(&cfg, log, cache), + Krystal: krystal.NewService(&cfg, log, cache, sentry), GeckoTerminal: geckoterminal.NewService(&cfg), - DexScreener: dexscreener.NewService(), + DexScreener: dexscreener.NewService(sentry), Github: github.NewService(&cfg, log), - Ethplorer: ethplorer.NewService(), - FriendTech: friendtech.NewService(&cfg), + Ethplorer: ethplorer.NewService(sentry), + FriendTech: friendtech.NewService(&cfg, sentry), Sentry: sentrygo.New(&cfg, log), }, nil } diff --git a/pkg/service/skymavis/adapter.go b/pkg/service/skymavis/adapter.go index fe37613e1..2978aa497 100644 --- a/pkg/service/skymavis/adapter.go +++ b/pkg/service/skymavis/adapter.go @@ -9,9 +9,16 @@ import ( "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) +var ( + sentryTags = map[string]string{ + "type": "system", + } +) + func (s *skymavis) doCacheNft(address string) (string, error) { return s.cache.GetString(fmt.Sprintf("%s-%s", nftKey, strings.ToLower(address))) } @@ -93,10 +100,24 @@ func (s *skymavis) doNetworkNfts(address string) (*response.AxieMarketNftRespons }) if err != nil { s.logger.Fields(logger.Fields{"status": status}).Error(err, "[skymavis.GetOwnedAxies] util.SendRequest() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Skymavis - GetOwnedAxies failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } if status != 200 { s.logger.Fields(logger.Fields{"status": status}).Error(err, "[skymavis.GetOwnedAxies] failed to query") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Skymavis - GetOwnedAxies failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } @@ -165,10 +186,24 @@ func (s *skymavis) doNetworkFarming(address string) (*response.WalletFarmingResp }) if err != nil { s.logger.Fields(logger.Fields{"status": status}).Error(err, "[skymavis.GetAddressFarming] util.SendRequest() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Skymavis - GetAddressFarming failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } if status != 200 { s.logger.Fields(logger.Fields{"status": status}).Error(err, "[skymavis.GetAddressFarming] failed to query") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Skymavis - GetAddressFarming failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } @@ -194,6 +229,13 @@ func (s *skymavis) doNetworkInternalTxs(hash string) (*response.SkymavisTransact }) if err != nil { s.logger.Fields(logger.Fields{"status": status}).Error(err, "[skymavis.doNetworkInternalTxs] util.SendRequest() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Skymavis - doNetWorkInternalTxs failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "hash": hash, + }, + }) return nil, err } if status != 200 { diff --git a/pkg/service/skymavis/skymavis.go b/pkg/service/skymavis/skymavis.go index c8138d0a8..91cc31666 100644 --- a/pkg/service/skymavis/skymavis.go +++ b/pkg/service/skymavis/skymavis.go @@ -7,19 +7,22 @@ import ( "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" ) type skymavis struct { cfg *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func New(cfg *config.Config, cache cache.Cache) Service { +func New(cfg *config.Config, cache cache.Cache, sentry sentrygo.Service) Service { return &skymavis{ cfg: cfg, logger: logger.NewLogrusLogger(), cache: cache, + sentry: sentry, } } diff --git a/pkg/service/solscan/adapter.go b/pkg/service/solscan/adapter.go index a1a9d7028..739f288db 100644 --- a/pkg/service/solscan/adapter.go +++ b/pkg/service/solscan/adapter.go @@ -7,6 +7,7 @@ import ( "time" "github.com/defipod/mochi/pkg/logger" + "github.com/defipod/mochi/pkg/service/sentrygo" ) func (s *solscan) doCacheTransaction(address string) (string, error) { @@ -19,6 +20,13 @@ func (s *solscan) doNetworkTransaction(address string) ([]TransactionListItem, e err := s.fetchSolscanData(url, &res) if err != nil { s.logger.Fields(logger.Fields{"url": url}).Error(err, "[solscan.getTransactions] s.fetchSolscanData() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - doNetworkTransaction failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } @@ -41,6 +49,13 @@ func (s *solscan) doNetworkTransactionDetail(signature string) (*TransactionDeta err := s.fetchSolscanData(url, &res) if err != nil { s.logger.Fields(logger.Fields{"url": url}).Error(err, "[solscan.getTransactionDetail] s.fetchSolscanData() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - doNetworkTransactionDetail failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "signature": signature, + }, + }) return nil, err } @@ -62,6 +77,13 @@ func (s *solscan) doNetworkTokenMetadata(tokenAddress string) (*TokenMetadataRes err := s.fetchSolscanData(url, &res) if err != nil { s.logger.Fields(logger.Fields{"url": url}).Error(err, "[solscan.getTokenMetadata] s.fetchSolscanData() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - doNetworkTokenMetadata failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "tokenAddress": tokenAddress, + }, + }) return nil, err } @@ -83,6 +105,13 @@ func (s *solscan) doNetworkTokenBalance(address string) ([]TokenAmountItem, erro err := s.fetchSolscanData(url, &res) if err != nil { s.logger.Fields(logger.Fields{"url": url}).Error(err, "[solscan.getTokenBalances] s.fetchSolscanData() failed") + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - doNetworkTokenBalance failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } diff --git a/pkg/service/solscan/solscan.go b/pkg/service/solscan/solscan.go index 90b8d67bd..2aef32080 100644 --- a/pkg/service/solscan/solscan.go +++ b/pkg/service/solscan/solscan.go @@ -10,19 +10,22 @@ import ( "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" resp "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" ) type solscan struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func NewService(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &solscan{ config: cfg, logger: l, cache: cache, + sentry: sentry, } } @@ -33,6 +36,9 @@ var ( solscanTransactionDetailKey = "solscan-transaction-detail" solscanTokenMetadataKey = "solscan-token-metadata" solscanTokenBalanceKey = "solscan-token-balance" + sentryTags = map[string]string{ + "type": "system", + } ) func (s *solscan) GetCollectionBySolscanId(id string) (*resp.CollectionDataResponse, error) { @@ -48,6 +54,13 @@ func (s *solscan) GetCollectionBySolscanId(id string) (*resp.CollectionDataRespo response, err := client.Do(request) if err != nil { + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - GetCollectionBySolscanId failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "id": id, + }, + }) return nil, err } @@ -77,6 +90,14 @@ func (s *solscan) GetNftTokenFromCollection(id, page string) (*resp.NftTokenData response, err := client.Do(request) if err != nil { + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Solscan - GetNftTokenFromCollection failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "id": id, + "page": page, + }, + }) return nil, err } diff --git a/pkg/service/sui/adapter.go b/pkg/service/sui/adapter.go index 99e88d47d..d0649560f 100644 --- a/pkg/service/sui/adapter.go +++ b/pkg/service/sui/adapter.go @@ -11,6 +11,7 @@ import ( "time" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" "github.com/defipod/mochi/pkg/util" ) @@ -60,6 +61,13 @@ func (s *SuiService) doNetworkBalance(address string) (*response.SuiAllBalance, resp, err := client.Do(request) if err != nil { + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Sui - doNetWorkBalance failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } @@ -109,6 +117,13 @@ func (s *SuiService) doNetworkCoinMetadata(coinType string) (*response.SuiCoinMe resp, err := client.Do(request) if err != nil { + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Sui - doNetWorkCoinMetadaata failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "coinType": coinType, + }, + }) return nil, err } @@ -221,6 +236,13 @@ func (s *SuiService) doNetworkTransactionBlock(address string) (*response.SuiTra request.Header.Add("Content-Type", "application/json") resp, err := client.Do(request) if err != nil { + s.sentry.CaptureErrorEvent(sentrygo.SentryCapturePayload{ + Message: fmt.Sprintf("[API mochi] - Sui - doNetWorkTransactionBlock failed %v", err), + Tags: sentryTags, + Extra: map[string]interface{}{ + "address": address, + }, + }) return nil, err } diff --git a/pkg/service/sui/sui.go b/pkg/service/sui/sui.go index 80f2aac7a..240a645d4 100644 --- a/pkg/service/sui/sui.go +++ b/pkg/service/sui/sui.go @@ -7,15 +7,17 @@ import ( "github.com/defipod/mochi/pkg/config" "github.com/defipod/mochi/pkg/logger" "github.com/defipod/mochi/pkg/response" + "github.com/defipod/mochi/pkg/service/sentrygo" ) type SuiService struct { config *config.Config logger logger.Logger cache cache.Cache + sentry sentrygo.Service } -func New(cfg *config.Config, l logger.Logger, cache cache.Cache) Service { +func New(cfg *config.Config, l logger.Logger, cache cache.Cache, sentry sentrygo.Service) Service { return &SuiService{ config: cfg, logger: l, @@ -29,6 +31,9 @@ var ( suiAddressAssetsKey = "sui-address-asset" suiTransactionBlockKey = "sui-transaction-block" suiAddressTxnKey = "sui-address-txn" + sentryTags = map[string]string{ + "type": "system", + } ) func (s *SuiService) GetBalance(address string) (*response.SuiAllBalance, error) {