1
votes

I this service grabs the token from two places and attaches the token in every HTTP request as a header. I don't know why but I'm getting this error. I'm handling async but still, this task is getting canceled.

public class TokenService : DelegatingHandler, IHostedService
    {
        public IConfiguration Configuration { get; }
        private Timer _timer;
        public IHttpClientFactory _clientFactory;
        protected HttpClient _client_SB;
        protected HttpClient _client_Opsman_SB;
        private readonly IServiceScopeFactory _scopeFactory;
        string connectionString = "";

        public TokenService(IConfiguration configuration, IHttpClientFactory clientFactory, IServiceScopeFactory scopeFactory)
        {
            Configuration = configuration;
            _clientFactory = clientFactory;
            _scopeFactory = scopeFactory;
            connectionString = Configuration.GetConnectionString("DefaultConnection");
            _client_SB = _clientFactory.CreateClient("TestEnv");
            _client_Opsman_SB = _clientFactory.CreateClient("OpsmanTestEnv");
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(GetAccessToken, null, 0, 3300000);
            _timer = new Timer(GetAccessTokenOpsMan, null, 0, 3300000);
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            //Timer does not have a stop. 
            _timer?.Change(Timeout.Infinite, 0);
            return Task.CompletedTask;
        }

        public async Task<Token> GetToken(Uri authenticationUrl, Dictionary<string, string> authenticationCredentials)
        {
            HttpClient client = new HttpClient();
            FormUrlEncodedContent content = new FormUrlEncodedContent(authenticationCredentials);
            HttpResponseMessage response = await client.PostAsync(authenticationUrl, content);

            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                string message = String.Format("POST failed. Received HTTP {0}", response.StatusCode);
                throw new ApplicationException(message);
            }

            string responseString = await response.Content.ReadAsStringAsync();
            Token token = JsonConvert.DeserializeObject<Token>(responseString);

            return token;
        }
        private void GetAccessToken(object state)
        {
            Dictionary<string, string> authenticationCredentials_sb = Configuration.GetSection("TestEnvironment:Credentials").GetChildren().Select(x => new KeyValuePair<string, string>(x.Key, x.Value)).ToDictionary(x => x.Key, x => x.Value);
            Token token_sb = GetToken(new Uri(Configuration["TestEnvironment:URL"]), authenticationCredentials_sb).Result;

            _client_SB.DefaultRequestHeaders.Add("Authorization", $"Bearer {token_sb.AccessToken}");
        }

        private void GetAccessTokenOpsMan(object state)
        {

            Dictionary<string, string> authenticationCredentials_opsman_sb = Configuration.GetSection("OpsManTestEnvironment:Credentials").GetChildren().Select(x => new KeyValuePair<string, string>(x.Key, x.Value)).ToDictionary(x => x.Key, x => x.Value);
            Token opsman_token_sb = GetToken(new Uri(Configuration["OpsManTestEnvironment:URL"]), authenticationCredentials_opsman_sb).Result;
            _client_Opsman_SB.DefaultRequestHeaders.Add("Authorization", $"Bearer {opsman_token_sb.AccessToken}");
        }
    }

Unhandled Exception: System.AggregateException: One or more errors occurred. (A task was canceled.) ---> System.Threading.Tasks.TaskCanceledException: A task was canceled. --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at ProjectEcho.Services.TestService.GetAccessTokenOpsMan(Object state) in c:\agent_Work09\73\s\Services\TestService.cs:line 73 at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.TimerQueueTimer.CallCallback() at System.Threading.TimerQueueTimer.Fire() at System.Threading.TimerQueue.FireNextTimers() }

1
This is almost certainly your HTTP call that is timing outKevin Gosse
I'd concur with @KevinGosse on that. Here is a previous answer I provided on something similar.Mr Moose
so increasing the timeout could be the solution?Sam
Where you are using a variable of type HttpClient try doing something like httpClient.Timeout = new TimeSpan(0, asyncTimeoutInMins, 0); where asyncTimeoutInMins is some value you expect to have your token returned by. In fact look at the other constructors for TimeSpan as you shouldn't be waiting minutes for a token. Set it to some value to at least test that this resolves your issue and go from there.Mr Moose
@MrMoose its not a code issue, it turns out that its a network issue the API it is calling hosted on the same foundation as the app so it is kinda looping in itSam

1 Answers

0
votes

You will need to look into the inner exception, you are just reporting the AggregateException but that is just a wrapper of the real INNER exception(s).

catch (AggregateException agg_ex)
{
   //just get first exception, it will contain the most relevant error.
   var ex = agg_ex.InnerExceptions[0];
}