diff --git a/src/EoaServer.Application.Contracts/EoaServer.Application.Contracts.csproj b/src/EoaServer.Application.Contracts/EoaServer.Application.Contracts.csproj index fed6d44..a5cf60a 100644 --- a/src/EoaServer.Application.Contracts/EoaServer.Application.Contracts.csproj +++ b/src/EoaServer.Application.Contracts/EoaServer.Application.Contracts.csproj @@ -37,6 +37,7 @@ + diff --git a/src/EoaServer.Application.Contracts/HandlerExceptionService.cs b/src/EoaServer.Application.Contracts/HandlerExceptionService.cs new file mode 100644 index 0000000..373366b --- /dev/null +++ b/src/EoaServer.Application.Contracts/HandlerExceptionService.cs @@ -0,0 +1,70 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using AElf.ExceptionHandler; + +namespace EoaServer; + + +public class HandlerExceptionService +{ + public static async Task HandleWithReturn(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return, + }; + } + + public static async Task HandleWithContinue(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Continue, + }; + } + + public static async Task HandleWithReturnNull(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return, + ReturnValue = null + }; + } + + public static async Task HandleWithReThrow(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Rethrow + }; + } + + public static async Task HandleWithHttpException(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Throw, + ReturnValue = new HttpRequestException(ex.Message) + }; + } + + public static async Task HandleWithReturnMinusOne(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return, + ReturnValue = -1 + }; + } + + public static async Task HandleWithReturnLongMinusOne(Exception ex) + { + return new FlowBehavior + { + ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return, + ReturnValue = -1L + }; + } +} \ No newline at end of file diff --git a/src/EoaServer.Application/Common/Provider/AElfScanDataProvider.cs b/src/EoaServer.Application/Common/Provider/AElfScanDataProvider.cs index c2f186d..d5f8285 100644 --- a/src/EoaServer.Application/Common/Provider/AElfScanDataProvider.cs +++ b/src/EoaServer.Application/Common/Provider/AElfScanDataProvider.cs @@ -36,43 +36,64 @@ public AElfScanDataProvider(IHttpClientProvider httpClientProvider, _logger = logger; } - [ExceptionHandler(typeof(Exception), Message = "GetTokenListAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetTokenListAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task> GetTokenListAsync(string chainId, string search) { var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanTokenListApi; var requestUrl = $"{url}?chainId={chainId}&fuzzySearch={search.ToLower()}&skipCount=0&maxResultCount={LimitedResultRequestDto.MaxMaxResultCount}"; - var chainTokenList = await _httpClientProvider.GetDataAsync>(requestUrl); + var chainTokenList = await _httpClientProvider.GetDataAsync>(requestUrl, _aelfScanOptions.Timeout); + if (chainTokenList == null) + { + _logger.LogError($"Http request: {requestUrl} get null response"); + } return chainTokenList; } - [ExceptionHandler(typeof(Exception), Message = "GetAddressTokenAssetsAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetAddressTokenAssetsAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task GetAddressTokenAssetsAsync(string chainId, string address) { var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanUserTokenAssetsApi; var requestUrl = $"{url}?address={address}&chainId={chainId}&skipCount=0&MaxResultCount={LimitedResultRequestDto.MaxMaxResultCount}"; - var chainTokenList = await _httpClientProvider.GetDataAsync(requestUrl); + var chainTokenList = await _httpClientProvider.GetDataAsync(requestUrl, _aelfScanOptions.Timeout); + if (chainTokenList == null) + { + _logger.LogError($"Http request: {requestUrl} get null response"); + } return chainTokenList; } - [ExceptionHandler(typeof(Exception), Message = "GetAddressNftListAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetAddressNftListAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task GetAddressNftListAsync(string chainId, string address) { var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanUserNFTAssetsApi; var requestUrl = $"{url}?address={address}&chainId={chainId}&skipCount=0&maxResultCount={LimitedResultRequestDto.MaxMaxResultCount}"; - var chainTokenList = await _httpClientProvider.GetDataAsync(requestUrl); + var chainTokenList = await _httpClientProvider.GetDataAsync(requestUrl, _aelfScanOptions.Timeout); + if (chainTokenList == null) + { + _logger.LogError($"Http request: {requestUrl} get null response"); + } return chainTokenList; } - [ExceptionHandler(typeof(Exception), Message = "GetTransactionDetailAsync Error", LogOnly = true)] public async Task GetTransactionDetailAsync(string chainId, string transactionId) { var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanTransactionDetailApi; var requestUrl = $"{url}?TransactionId={transactionId}&ChainId={chainId}"; - var txnDto = await _httpClientProvider.GetDataAsync(requestUrl); - return txnDto; + + try + { + var txnDto = await _httpClientProvider.GetDataAsync(requestUrl, _aelfScanOptions.Timeout); + return txnDto; + } + catch (Exception e) + { + _logger.LogError($"GetTransactionDetailAsync error. Request: {requestUrl}. Exception: {e}"); + } + + return null; } - [ExceptionHandler(typeof(Exception), Message = "GetAddressTransactionsAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetAddressTransactionsAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task GetAddressTransactionsAsync(string chainId, string address, int skipCount, int maxResultCount) { var baseUrl = _aelfScanOptions.BaseUrl; @@ -82,11 +103,15 @@ public async Task GetAddressTransactionsAsync(string ch transactionsUrl += $"address={address}&" + $"skipCount={skipCount}&" + $"maxResultCount={maxResultCount}"; - var response = await _httpClientProvider.GetDataAsync(transactionsUrl); + var response = await _httpClientProvider.GetDataAsync(transactionsUrl, _aelfScanOptions.Timeout); + if (response == null) + { + _logger.LogError($"Http request: {transactionsUrl} get null response"); + } return response; } - [ExceptionHandler(typeof(Exception), Message = "GetAddressTransactionsAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetAddressTransfersAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task GetAddressTransfersAsync(string chainId, string address, int tokenType, int skipCount, int maxResultCount, string symbol) { @@ -98,18 +123,19 @@ public async Task GetAddressTransfersAsync(string chai $"address={address}&" + $"skipCount={skipCount}&" + $"maxResultCount={maxResultCount}"; - return await _httpClientProvider.GetDataAsync(nftTransfersUrl); + var response = await _httpClientProvider.GetDataAsync(nftTransfersUrl, _aelfScanOptions.Timeout); + return response; } - [ExceptionHandler(typeof(Exception), Message = "GetIndexerTokenInfoAsync Error", LogOnly = true)] + [ExceptionHandler(typeof(Exception), Message = "GetIndexerTokenInfoAsync Error", TargetType = typeof(HandlerExceptionService), MethodName = nameof(HandlerExceptionService.HandleWithReturnNull))] public async Task GetIndexerTokenInfoAsync(string chainId, string symbol) { var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanTokenInfoApi; var requestUrl = $"{url}?Symbol={symbol}&ChainId={chainId}"; - var tokenInfoResult = await _httpClientProvider.GetDataAsync(requestUrl); + var tokenInfoResult = await _httpClientProvider.GetDataAsync(requestUrl, _aelfScanOptions.Timeout); if (tokenInfoResult == null) { - _logger.LogError($"{requestUrl} get null response"); + _logger.LogError($"Http request: {requestUrl} get null response"); } return tokenInfoResult; } diff --git a/src/EoaServer.Application/Common/Provider/HttpClientProvider.cs b/src/EoaServer.Application/Common/Provider/HttpClientProvider.cs index 14ce65e..b36d8d9 100644 --- a/src/EoaServer.Application/Common/Provider/HttpClientProvider.cs +++ b/src/EoaServer.Application/Common/Provider/HttpClientProvider.cs @@ -6,6 +6,7 @@ using System.Net.Mime; using System.Text; using System.Threading.Tasks; +using AElf.ExceptionHandler; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -18,7 +19,8 @@ public class HttpClientProvider : IHttpClientProvider, ISingletonDependency { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; - + + private const int DefaultTimeout = 3000; public HttpClientProvider(IHttpClientFactory httpClientFactory, ILogger logger) { _httpClientFactory = httpClientFactory; @@ -43,10 +45,10 @@ public async Task GetAsync(string url, Dictionary headers) return JsonConvert.DeserializeObject(response); } - public async Task GetDataAsync(string url, int timeout = 1000) + public async Task GetDataAsync(string url, int? timeout = null) { var client = _httpClientFactory.CreateClient(); - client.Timeout = new TimeSpan(0, 0, 0, 0, timeout); + client.Timeout = TimeSpan.FromMilliseconds(timeout.GetValueOrDefault(DefaultTimeout) <= 0 ? DefaultTimeout : timeout.GetValueOrDefault(DefaultTimeout)); var response = await client.GetStringAsync(url); var json = JObject.Parse(response); return json["data"].ToObject(); diff --git a/src/EoaServer.Application/Common/Provider/IHttpClientProvider.cs b/src/EoaServer.Application/Common/Provider/IHttpClientProvider.cs index 44dfe3f..3e12812 100644 --- a/src/EoaServer.Application/Common/Provider/IHttpClientProvider.cs +++ b/src/EoaServer.Application/Common/Provider/IHttpClientProvider.cs @@ -7,7 +7,7 @@ public interface IHttpClientProvider { Task GetAsync(string url); Task GetAsync(string url, Dictionary headers); - Task GetDataAsync(string url, int timeout = 1000); + Task GetDataAsync(string url, int? timeout = null); Task PostAsync(string url); Task PostAsync(string url, object paramObj); Task PostAsync(string url, object paramObj, Dictionary headers); diff --git a/src/EoaServer.Application/Options/AElfScanOptions.cs b/src/EoaServer.Application/Options/AElfScanOptions.cs index 6fa3fb5..99849d4 100644 --- a/src/EoaServer.Application/Options/AElfScanOptions.cs +++ b/src/EoaServer.Application/Options/AElfScanOptions.cs @@ -3,4 +3,5 @@ namespace EoaServer.Options; public class AElfScanOptions { public string BaseUrl { get; set; } + public int Timeout { get; set; } } \ No newline at end of file diff --git a/src/EoaServer.HttpApi.Host/appsettings.json b/src/EoaServer.HttpApi.Host/appsettings.json index c030acd..a9acd72 100755 --- a/src/EoaServer.HttpApi.Host/appsettings.json +++ b/src/EoaServer.HttpApi.Host/appsettings.json @@ -92,7 +92,8 @@ "DataBase": "EoaServerOrleansDB" }, "AElfScanOptions": { - "BaseUrl": "https://testnet.aelfscan.io" + "BaseUrl": "https://testnet.aelfscan.io", + "Timeout": 3000 }, "ActivityOptions": { "ActivityTransactionFeeFix": [