fix(android): a conflict answers 422, not 409

The retry path finally ran, and did not recognise what it was handed. A
desktop publishing between our read and our write earns a 422, not a 409, so
the save failed instead of retrying - which is exactly what a never-exercised
path hides: it was written, it compiled, it was even commented, and it did
not fire.

Gitea answers 409 when the sha no longer matches and 422 when it is missing
or the request is judged unprocessable, "file already exists" among them.
Both say the same thing to us: the sha is stale. Re-reading and retrying is
right for both and cannot clobber anything - the retry publishes against the
fresh sha. A genuinely malformed body would fail again and give up after
three tries, carrying Gitea's own words.

The log now prints which code it was, rather than assuming.
This commit is contained in:
r-zakarya
2026-08-21 16:56:48 +01:00
parent 31bf4f920c
commit 30b2413ea3
3 changed files with 34 additions and 8 deletions
+14 -2
View File
@@ -40,7 +40,7 @@ type
ssRefused, // 403 : HTTPS exige par le serveur
ssHttpError, // autre code
ssNetworkError, // rien n'a repondu
/// 409 : le sha envoye n'est plus celui du fichier - un autre appareil a
/// 409 ou 422 : le sha envoye n'est plus celui du fichier - un autre appareil a
/// publie entre notre lecture et notre ecriture. L'appelant doit relire,
/// refusionner et renvoyer, pas reessayer tel quel.
ssConflict
@@ -232,7 +232,19 @@ begin
// prochaine ecriture - sans lui il faudrait relire pour publier.
Result.ETag := ShaFromPutResponse(LResync.DataString);
end;
409: Result.Status := ssConflict;
// 409 ET 422 : DANS LES DEUX CAS LE SHA N'EST PLUS LE BON.
//
// Gitea rend 409 quand le sha envoye ne correspond plus, et 422 quand
// il manque ou qu'il juge la demande irrecevable - dont le cas « ce
// fichier existe deja » d'une creation. Mesure a l'appui : un poste
// qui publie entre notre lecture et notre ecriture nous a valu un
// 422, pas un 409, et l'enregistrement echouait au lieu de reprendre.
//
// Relire et recommencer est la bonne reponse aux deux, et elle est
// sans danger : la reprise republie avec le sha frais, donc elle
// n'ecrase jamais rien. Un vrai corps mal forme echouerait de nouveau
// et sortirait au bout de trois essais, avec le texte de Gitea.
409, 422: Result.Status := ssConflict;
else
Result.Status := ssHttpError;
// LE CORPS, TOUJOURS. Il etait remplace par un message fige sur 401