Octokit API Exception: "is at xx but expected yy" - c#

Im working on a small school project where i need to update an file from my github repo.
Everything worked fine until i got an error out of nowhere.
I am using Octokit .net with a C# WPF Application. Here the Exception:
Octokit.ApiException: "is at 1ce907108c4582d5a0986d3a37b2777e271a0105 but expected 47fa57debd39ee6a63f24d39e9513f87814a5ed6"
I dont know why this error shows up, because i didn't change anything before the error happend and now nothing works anymore. Can someone help me with this?
Here the code:
private static async void UpdateFile(string fileName, string fileContent)
{
var ghClient = new GitHubClient(new ProductHeaderValue(HEADER));
ghClient.Credentials = new Credentials(API_KEY);
// github variables
var owner = OWNER;
var repo = REPO;
var branch = "main";
var targetFile = fileName;
try
{
// try to get the file (and with the file the last commit sha)
var existingFile = await ghClient.Repository.Content.GetAllContentsByRef(owner, repo, targetFile, branch);
// update the file
var updateChangeSet = await ghClient.Repository.Content.UpdateFile(owner, repo, targetFile,
new UpdateFileRequest("API Config Updated", fileContent, existingFile.First().Sha, branch));
}
catch (Octokit.NotFoundException)
{
// if file is not found, create it
var createChangeSet = await ghClient.Repository.Content.CreateFile(owner, repo, targetFile, new CreateFileRequest("API Config Created", fileContent, branch));
}
}

I found the issue after a bit of experimenting.
I updated 3 files at the same time, it turns out Octokit can't handle more than 1 request at the same time...
If you're stuck on this problem too, just add a delay of ~2 seconds before posting a new request.

Related

Large Fileupload to Azure with Blob Storage with BlobContainerClient

I want to upload large Files to Azure Blob Storage (500-2000MB) and I try to do this with the following code:
private BlobContainerClient containerClient;
public async Task<UploadResultDto> Upload(FileInfo fileInfo, string remotePath)
{
try
{
var blobClient = containerClient.GetBlobClient(remotePath + "/" + fileInfo.Name);
var transferOptions = new StorageTransferOptions
{
MaximumConcurrency = 1,
MaximumTransferSize = 10485760,
InitialTransferSize = 10485760
};
await using var uploadFileStream = File.OpenRead(fileInfo.FullName);
await blobClient.UploadAsync(uploadFileStream, transferOptions: transferOptions);
uploadFileStream.Close();
return new UploadResultDto()
{
UploadSuccessfull = true
};
}
catch (Exception ex)
{
Log.Error(ex,$"Error while uploading File {fileInfo.FullName}");
}
return new UploadResultDto()
{
UploadSuccessfull = false
};
}
I instantly get the following message:
The specified blob or block content is invalid.
RequestId:c5c2d925-701e-0035-7ce0-8691a6000000
Time:2020-09-09T19:33:40.9559646Z
Status: 400 (The specified blob or block content is invalid.)
If i remove the InitialTransferSize from the StorageTransferOptions, i get the following error after some time:
retry failed after 6 tries. (The operation was canceled.)
As far as I understood the new SDK, the upload in chunks and therefore the whole handling of the blockIds etc. should be done by the SDK. Or am I wrong?
Does anybody know why this is not working? I did not find anything different then this for BlobContainerClient, only for the old cloudblobcontainer.
Update:
Some Additional Informations:
It is a .netCore 3.1 Application which runs with the library Topshelf as a Windows Service
The second part of your question after you remove the InitialTransferSize from the StorageTransferOptions is similar to the issue in this question.
You may be able to resolve the issue by setting the timeouts for the blob client as follows:
var blobClientOptions = new BlobClientOptions
{
Transport = new HttpClientTransport(new HttpClient { Timeout = Timeout.InfiniteTimeSpan }),
Retry = { NetworkTimeout = Timeout.InfiniteTimeSpan }
};
InfiniteTimeSpan is probably overkill, but at least it will prove if that was the issue.
Those settings got rid of the "retry failed after 6 tries" error for me and got the upload when I started using the Azure.Storage.Blobs v12.8.0 package
I create a new console app and test with your code which works very well.
1.Confirm that you do not have inconsistencies in assemblies. Remove the earlier version of Azure.Storage.Blobs and update you itto the latest version.
And why your containerClient is private? You could set it in Upload method with following code:
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionstring);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("containerName");
var blobClient = containerClient.GetBlobClient(remotePath + "/" +fileInfo.Name);
I was not able to get it working with version 12.6.0...
I downgraded to Microsoft.Azure.Storage.Blob v11 and implemented the upload based on this thread
https://stackoverflow.com/a/58741171/765766
This works fine for me now

Xamarin Media Plugin Crashes when second photo is taken

I am using the Plugin.Media (jamesmontemagno/MediaPlugin) plugin for Xamarin and I am having an issue with accepting a picture. When I take the second picture (the first picture works fine) and I click to accept the image the whole app crashes with no output as to the error. I have tried trapping the error but cannot find where it is occurring. I have as suggested removing the min SDK from Android manifest, but the crash still happens.
I have tried looking through the output in visual studio but it is always different. I am assuming the code works as it takes the image and gives me data back, to be clear, it only happens when trying to accept the second image.
private string GetTimestamp(DateTime value)
{
string timestamp = value.ToString("yyyyMMddHHmmssfff");
string filename = timestamp + ".jpg";
return filename;
}
public Command CaptureImage => new Command(TakePicture);
private async void TakePicture()
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
//Some message
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "FoodSnap",
Name = GetTimestamp(DateTime.Now) //Gets a unique file name,
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Custom,
CustomPhotoSize = 50
});
if (file == null)
return;
FilePath = file.Path;
}
I am completely stumped as to why this is happening. I am also having trouble refreshing my ViewModel when data changes in the page I am using to take the image. I can't help wondering if this has something to do with it.
I solved the problem by testing each line of code. Once I removed PhotoSize = Plugin.Media.Abstractions.PhotoSize.Custom I could take as many pictures as I need. I did use the Github information for the plugin.
I would be interested to know what I did wrong to cause the error. I would suggest that I have misunderstood the tutorial on Github.

Tfs Check-in using PendAdd: The array must contain at least one element

So I'm having a problem with automating my code to check-in files to TFS, and it's been driving me up the wall! Here is my code:
string location = AppDomain.CurrentDomain.BaseDirectory;
TfsTeamProjectCollection baseUserTpcConnection = new TfsTeamProjectCollection(uriToTeamProjectCollection);
IIdentityManagementService ims = baseUserTpcConnection.GetService<IIdentityManagementService>();
TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName, #"PROD1\JR", MembershipQuery.None, ReadIdentityOptions.None);
TfsTeamProjectCollection impersonatedTpcConnection = new TfsTeamProjectCollection(uriToTeamProjectCollection, identity.Descriptor);
VersionControlServer sourceControl = impersonatedTpcConnection.GetService<VersionControlServer>();
Workspace workspace = sourceControl.CreateWorkspace("MyTempWorkspace", sourceControl.AuthorizedUser);
String topDir = null;
try
{
Directory.CreateDirectory(location + "TFS");
String localDir = location + "TFS";
workspace.Map("$/Automation/", localDir);
workspace.Get();
destinationFile = Path.Combine(localDir, Name + ".xml");
string SeconddestinationFile = Path.Combine(localDir, Name + ".ial");
bool check = sourceControl.ServerItemExists(destinationFile, ItemType.Any);
PendingChange[] pendingChanges;
File.Move(sourceFile, destinationFile);
File.Copy(destinationFile, sourceFile, true);
File.Move(SecondsourceFile, SeconddestinationFile);
File.Copy(SeconddestinationFile, SecondsourceFile, true);
if (check == false)
{
workspace.PendAdd(localDir,true);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
else
{
workspace.PendEdit(destinationFile);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
and the problem is that whenever it's NEW files (PendEdit works correctly when the files already exist in TFS) that my code is attempting to check in, and it runs through this code:
if (check == false)
{
workspace.PendAdd(localDir,true);
pendingChanges = workspace.GetPendingChanges();
workspace.CheckIn(pendingChanges, Comments);
}
The files, instead of being in the included changes in pending changes, are instead in the excluded changes like so:
and when the line that actually does the check-in runs, I'll get a "The array must contain at least one element" error, and the only way to fix it is to manually add those detected changes, and promote them to included changes, and I simply can't for the life of me figure out how to do that programatically though C#. If anyone has any guidance on what direction I should take for this, I would really appreciate it! Thank you!
Edit: I've also discovered another way to solve this by reconciling the folder, which also promotes the detected changes, but again the problem is I can't seem to figure out how to program that to do it automatically.
I know that running the visual studio developer command prompt, redirecting to the folder that this mapping is in, and the running "tf reconcile /promote" is one way, but I can only automate that as far as the /promote part, because that brings up a toolbox that a user would have to input into, which defeats the purpose of the automation. I'm at a loss.
Next Edit in response to TToni:
Next Edit in response to TToni:
I'm not entirely sure if I did this CreateWorkspaceParameters correctly (see picture 1), but this time it gave the same error, but the files were not even in the excluded portions. They just didn't show up anywhere in the pending changes (see picture 2).
Check this blog:
The workspace has a method GetPendingChangesWithCandidates, which actually gets all the “Excluded” changes. Code snippet is as below:
private void PendChangesAndCheckIn(string pathToWorkspace)
{
//Get Version Control Server object
VersionControlServer vs = collection.GetService(typeof
(VersionControlServer)) as VersionControlServer;
Workspace ws = vs.TryGetWorkspace(pathToWorkspace);
//Do Delete and Copy Actions to local path
//Create a item spec from the server Path
PendingChange[] candidateChanges = null;
string serverPath = ws.GetServerItemForLocalItem(pathToWorkspace);
List<ItemSpec> its = new List<ItemSpec>();
its.Add(new ItemSpec(serverPath, RecursionType.Full));
//get all candidate changes and promote them to included changes
ws.GetPendingChangesWithCandidates(its.ToArray(), true,
out candidateChanges);
foreach (var change in candidateChanges)
{
if (change.IsAdd)
{
ws.PendAdd(change.LocalItem);
}
else if (change.IsDelete)
{
ws.PendDelete(change.LocalItem);
}
}
//Check In all pending changes
ws.CheckIn(ws.GetPendingChanges(), "This is a comment");
}

Windows Store App c# replace SQL Database in local storage

I am trying to overwrite the database in my local folder with one that is in my pictures directory I use the following
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
String picName = "SqlLiteWin8-1.db";
var file2 = await storageFolder.TryGetItemAsync(picName) as IStorageFile;
StorageFile fileCopy = await file2.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, "SqlLiteWin8-1.db", Windows.Storage.NameCollisionOption.ReplaceExisting);
It seems to work and the file is copied and overwrite the old one
Problem is when I run the app it still shows the old data
I checked by manually deleting the db in the local state folder of the app then running the code and it copies it to the folder.
I think its still using the database in the app package and not the one in the local folder
The database in the pictures directory is identical to the one stored in the app except 1 record is modified
I want to overwrite it so that I can just supply a new db file to users and the app will use the new data or is there a way of bypassing this and read the DB straight from the pictures directory instead of the local folder
one though was it uses the following code to check if the db exists and copies if it doesnt could this be what is causing it not to work
public static async Task<bool> checkDataBaseConnection()
{
bool isDatabaseExisting = false;
try
{
var uri = new Uri("ms-appx:///SqlLiteWin8-1.db"); //in application folder
var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
var destinationFolder = ApplicationData.Current.LocalFolder;//local appdata dir
//await file.DeleteAsync();
// var f = await destinationFolder.GetFileAsync("data.db3");
await file.CopyAsync(destinationFolder);
}
catch (Exception ex)
{
throw ex;
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("AFSMOJO.db");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
}
return isDatabaseExisting;
}
As always your help is greatly appreciated
Mark
Ignore my stupidity I found what was wrong I was connecting to the internal database instead of the local one
I changed
var db = new SQLiteConnection("SqlLiteWin8-1.db");
to
var db = new SQLiteConnection(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "SqlLiteWin8-1.db"));
and now i can change my db in the picture folder and it copies it to the local one and uses the new data
Thanks
Mark

await FileIO.ReadTextAsync giving error (edited: now using IStorageFile.OpenReadAsync)

I have this method in my project. This is what it is supposed to do:
It accepts a string which is the name of a file in a folder, AV, in the Assets folder of my project. It opens this file and performs some operations on it (not all of the required operations are in the code, yet).
public async static Task<Book> ParseFile(string bookN)
{
string bookName = bookN.Replace(" ", "");
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
string content = await FileIO.ReadTextAsync(bookFile);
string chapterStr = "CHAPTER";
int numOfChapters = Utilities.NumOfTimesStringOccurs(content, chapterStr);
Book book = new Book(bookName, numOfChapters);
//book.Chapters = new List<Chapter>(numOfChapters);
return book;
}
The problem is this line:
string content = await FileIO.ReadTextAsync(bookFile);
I know this because I set a breakpoint at the first line of the method. After stepping into the code, that particular line broke and opened the .g.cs file and was highlighting a line that apparently implied the compiler could not trace it. The line had to do with diagnostics.debugger or something like that.
The next step I tried was to put in a try and display the error in a MessageDialog. The error from this was:
Object reference was not found
or something similar.
I am thinking it could be that the line
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
is causing this since it has await so maybe the operation was not complete before the next line could be executed. But I don't expect it to be slow since the files in the folder are just 5 - 6 kB each on average.
I don't know what's wrong as this is my first time of using the Storage namespace classes as I'm new to Windows Store programming.
EDIT
After going through this MSDN Forum, I changed the code to this:
StorageFile bookFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AV/" + bookName + ".txt"));
Windows.Storage.Streams.IRandomAccessStream ras = await bookFile.OpenReadAsync();
Windows.Storage.Streams.DataReader reader = new Windows.Storage.Streams.DataReader(ras.GetInputStreamAt(0));
int numOfBytes = (int)ras.Size;
Byte[] bytes = new Byte[numOfBytes - 1];
await reader.LoadAsync((uint)numOfBytes);
reader.ReadBytes(bytes);
string content = Convert.ToBase64String(bytes);
This code should have actually worked because when I stepped through it during breakpoint, there was no error. But for some reason I can't fathom, the app doesn't react. When I set a breakpoint and I step into the code, it works (I mean it doesn't break; it does not give me the expected output) but when there is none, it "freezes".
I initially thought it was the size of the file (201 kB) that was taking too long so I changed it to another with a much lesser size (~3 kb) but it was the same. Now I'm thinking it has to do with async and await. I wish there was a way to do this without using them.
EDIT:
I'm not posting this an answer because I realized the it solved the issue but the question did not contain enough info to get an answer.
The solution was that I didn't use await on the method that was calling this method. I would have deleted it but I thought maybe it could be help someone. Thanks to everyone that attempted to solve it.
First You can check the property of your file(Assets/AV/someone.txt).
The Build Action should be Content. But not Embedded Resource or others.
If it still error. Then check if the file is existed.

Categories