Skip to content

Commit

Permalink
feat: add exception handler
Browse files Browse the repository at this point in the history
  • Loading branch information
mixhsnhd committed Dec 26, 2024
1 parent 004b5c5 commit b594edb
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
<PackageReference Include="AElf.ExceptionHandler.ABP" Version="8.2.0" />
</ItemGroup>

</Project>
70 changes: 70 additions & 0 deletions src/EoaServer.Application.Contracts/HandlerExceptionService.cs
Original file line number Diff line number Diff line change
@@ -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<FlowBehavior> HandleWithReturn(Exception ex)

Check warning on line 11 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.Silo)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 11 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.EntityEventHandler)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 11 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.AuthServer)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 11 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.HttpApi.Host)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
};
}

public static async Task<FlowBehavior> HandleWithContinue(Exception ex)

Check warning on line 19 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.Silo)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 19 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.EntityEventHandler)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 19 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.AuthServer)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 19 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.HttpApi.Host)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Continue,
};
}

public static async Task<FlowBehavior> HandleWithReturnNull(Exception ex)

Check warning on line 27 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.Silo)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 27 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.EntityEventHandler)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 27 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.AuthServer)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 27 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.HttpApi.Host)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = null
};
}

public static async Task<FlowBehavior> HandleWithReThrow(Exception ex)

Check warning on line 36 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.Silo)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 36 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.EntityEventHandler)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 36 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.AuthServer)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 36 in src/EoaServer.Application.Contracts/HandlerExceptionService.cs

View workflow job for this annotation

GitHub Actions / publish (EoaServer.HttpApi.Host)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Rethrow
};
}

public static async Task<FlowBehavior> HandleWithHttpException(Exception ex)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Throw,
ReturnValue = new HttpRequestException(ex.Message)
};
}

public static async Task<FlowBehavior> HandleWithReturnMinusOne(Exception ex)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = -1
};
}

public static async Task<FlowBehavior> HandleWithReturnLongMinusOne(Exception ex)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = -1L
};
}
}
58 changes: 42 additions & 16 deletions src/EoaServer.Application/Common/Provider/AElfScanDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ListResponseDto<TokenCommonDto>> 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<ListResponseDto<TokenCommonDto>>(requestUrl);
var chainTokenList = await _httpClientProvider.GetDataAsync<ListResponseDto<TokenCommonDto>>(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<GetAddressTokenListResultDto> 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<GetAddressTokenListResultDto>(requestUrl);
var chainTokenList = await _httpClientProvider.GetDataAsync<GetAddressTokenListResultDto>(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<GetAddressNftListResultDto> 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<GetAddressNftListResultDto>(requestUrl);
var chainTokenList = await _httpClientProvider.GetDataAsync<GetAddressNftListResultDto>(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<TransactionDetailResponseDto> GetTransactionDetailAsync(string chainId, string transactionId)
{
var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanTransactionDetailApi;
var requestUrl = $"{url}?TransactionId={transactionId}&ChainId={chainId}";
var txnDto = await _httpClientProvider.GetDataAsync<TransactionDetailResponseDto>(requestUrl);
return txnDto;

try
{
var txnDto = await _httpClientProvider.GetDataAsync<TransactionDetailResponseDto>(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<TransactionsResponseDto> GetAddressTransactionsAsync(string chainId, string address, int skipCount, int maxResultCount)
{
var baseUrl = _aelfScanOptions.BaseUrl;
Expand All @@ -82,11 +103,15 @@ public async Task<TransactionsResponseDto> GetAddressTransactionsAsync(string ch
transactionsUrl += $"address={address}&" +
$"skipCount={skipCount}&" +
$"maxResultCount={maxResultCount}";
var response = await _httpClientProvider.GetDataAsync<TransactionsResponseDto>(transactionsUrl);
var response = await _httpClientProvider.GetDataAsync<TransactionsResponseDto>(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<GetTransferListResultDto> GetAddressTransfersAsync(string chainId, string address, int tokenType,
int skipCount, int maxResultCount, string symbol)
{
Expand All @@ -98,18 +123,19 @@ public async Task<GetTransferListResultDto> GetAddressTransfersAsync(string chai
$"address={address}&" +
$"skipCount={skipCount}&" +
$"maxResultCount={maxResultCount}";
return await _httpClientProvider.GetDataAsync<GetTransferListResultDto>(nftTransfersUrl);
var response = await _httpClientProvider.GetDataAsync<GetTransferListResultDto>(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<IndexerTokenInfoDto> GetIndexerTokenInfoAsync(string chainId, string symbol)
{
var url = _aelfScanOptions.BaseUrl + "/" + CommonConstant.AelfScanTokenInfoApi;
var requestUrl = $"{url}?Symbol={symbol}&ChainId={chainId}";
var tokenInfoResult = await _httpClientProvider.GetDataAsync<IndexerTokenInfoDto>(requestUrl);
var tokenInfoResult = await _httpClientProvider.GetDataAsync<IndexerTokenInfoDto>(requestUrl, _aelfScanOptions.Timeout);
if (tokenInfoResult == null)
{
_logger.LogError($"{requestUrl} get null response");
_logger.LogError($"Http request: {requestUrl} get null response");
}
return tokenInfoResult;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,7 +19,8 @@ public class HttpClientProvider : IHttpClientProvider, ISingletonDependency
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<HttpClientProvider> _logger;


private const int DefaultTimeout = 3000;
public HttpClientProvider(IHttpClientFactory httpClientFactory, ILogger<HttpClientProvider> logger)
{
_httpClientFactory = httpClientFactory;
Expand All @@ -43,10 +45,10 @@ public async Task<T> GetAsync<T>(string url, Dictionary<string, string> headers)
return JsonConvert.DeserializeObject<T>(response);
}

public async Task<T> GetDataAsync<T>(string url, int timeout = 1000)
public async Task<T> GetDataAsync<T>(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<T>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public interface IHttpClientProvider
{
Task<T> GetAsync<T>(string url);
Task<T> GetAsync<T>(string url, Dictionary<string, string> headers);
Task<T> GetDataAsync<T>(string url, int timeout = 1000);
Task<T> GetDataAsync<T>(string url, int? timeout = null);
Task<T> PostAsync<T>(string url);
Task<T> PostAsync<T>(string url, object paramObj);
Task<T> PostAsync<T>(string url, object paramObj, Dictionary<string, string> headers);
Expand Down
1 change: 1 addition & 0 deletions src/EoaServer.Application/Options/AElfScanOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ namespace EoaServer.Options;
public class AElfScanOptions
{
public string BaseUrl { get; set; }
public int Timeout { get; set; }
}
3 changes: 2 additions & 1 deletion src/EoaServer.HttpApi.Host/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@
"DataBase": "EoaServerOrleansDB"
},
"AElfScanOptions": {
"BaseUrl": "https://testnet.aelfscan.io"
"BaseUrl": "https://testnet.aelfscan.io",
"Timeout": 3000
},
"ActivityOptions": {
"ActivityTransactionFeeFix": [
Expand Down

0 comments on commit b594edb

Please sign in to comment.