Open
Description
What happened?
Authenticating as a GitHub App but run into an issue when re-calling the request.
It throws an error at var aiAdapter = GitHubOctokit.Client.RequestAdapter.Create(aiAuthProvider);
:
Error Message:
This instance has already started one or more requests. Properties can only be modified before sending the first request.
at System.Net.Http.DelegatingHandler.CheckDisposedOrStarted()
at System.Net.Http.DelegatingHandler.set_InnerHandler(HttpMessageHandler value)
at GitHub.Octokit.Client.ClientFactory.ChainHandlersCollectionAndGetFirstLink(HttpMessageHandler finalHandler, DelegatingHandler[] handlers)
at GitHub.Octokit.Client.ClientFactory.Create(HttpMessageHandler finalHandler)
at GitHub.Octokit.Client.RequestAdapter.Create(IAuthenticationProvider authenticationProvider, HttpClient clientFactory)
Note
I tried setting the service as a singleton, but since the token expires every 8 hours, it ends up with the same issue.
Reproducing code
using GitHub;
using GitHub.Octokit.Client;
using GitHub.Octokit.Client.Authentication;
using System.Security.Cryptography;
namespace MyGitHubSertvice;
public class Program
{
public static async Task Main()
{
var settings = new GitHubServiceSettings
{
AppId = "<changeMe>",
InstallationId = "<changeMe>",
PrivateKey = File.ReadAllText(@"<changeMe>.pem"),
Owner = "<changeMe>",
RepositoryName = "<changeMe>",
IssueNumber = <changeMe>
};
var service = new GitHubService(settings);
// this part will pass fine <=======
await service.InitializeAsync();
var title1 = await service.GetIssueViaRestAsync();
Console.WriteLine(title1);
// consider 8 hours have been passed, and token is no longer valid
// await Task.Delay(TimeSpan.FromHours(8));
// this part will fail <=======
await service.InitializeAsync();
var title2 = await service.GetIssueViaRestAsync();
Console.WriteLine(title2);
}
}
public class GitHubServiceSettings
{
public required string AppId { get; set; }
public required string InstallationId { get; set; }
public required string PrivateKey { get; set; }
public required string Owner { get; set; }
public required string RepositoryName {get; set;}
public required int IssueNumber {get; set;}
}
public class GitHubService
{
private GitHubClient? _githubClient;
private GitHubServiceSettings _settings;
public GitHubService(GitHubServiceSettings settings)
{
_settings = settings;
}
// Need to initialize Async in the constructor, and the factory method will call it.
public async Task InitializeAsync()
{
await GetAuthorizationTokenAsync();
}
private async Task GetAuthorizationTokenAsync()
{
var githubAppTokenProvider = new GitHubAppTokenProvider();
var rsa = RSA.Create();
rsa.ImportFromPem(_settings.PrivateKey);
var aiAccessTokenProvider = new AppInstallationTokenProvider(_settings.AppId, rsa, _settings.InstallationId, githubAppTokenProvider);
var aiAuthProvider = new AppInstallationAuthProvider(aiAccessTokenProvider);
using var aiAdapter = RequestAdapter.Create(aiAuthProvider);
_githubClient = new GitHubClient(aiAdapter);
await Task.CompletedTask;
}
public async Task<string> GetIssueViaRestAsync()
{
var issue = await _githubClient!.Repos[_settings.Owner][_settings.RepositoryName].Issues[_settings.IssueNumber].GetAsync();
return issue?.Title!;
}
}
Versions
<PackageReference Include="GitHub.Octokit.SDK" Version="0.0.31" />
Code of Conduct
- I agree to follow this project's Code of Conduct
Metadata
Metadata
Assignees
Type
Projects
Status
🔥 Backlog