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:
+18
-5
@@ -843,11 +843,24 @@ Les trois verbes d'un coup, et depuis l'autre bout : **créer** (4), **modifier*
|
||||
(1), **supprimer** (1). Le `1 deleted` est celui qui comptait — la disparition
|
||||
locale ne prouvait rien, c'est la pierre tombale qui devait voyager.
|
||||
|
||||
Les étapes 1 à 3 de cette section sont donc closes. **Reste le 409** : depuis
|
||||
que l'enregistrement ne tire plus avant de publier, c'est lui seul qui garantit
|
||||
qu'une écriture du téléphone n'écrase pas le poste, et il n'a toujours jamais
|
||||
tourné. Le provoquer : synchroniser depuis le poste, puis enregistrer depuis le
|
||||
téléphone sans synchroniser d'abord.
|
||||
Les étapes 1 à 3 de cette section sont donc closes.
|
||||
|
||||
### Le conflit rend 422, pas 409 — corrigé 2026-08-21
|
||||
|
||||
Le chemin de reprise a enfin tourné, et il ne reconnaissait pas ce qu'il
|
||||
recevait. Un poste qui publie entre notre lecture et notre écriture nous vaut un
|
||||
**422**, pas un 409 : l'enregistrement échouait au lieu de reprendre.
|
||||
|
||||
Gitea rend 409 quand le sha envoyé ne correspond plus, et 422 quand il manque ou
|
||||
que la demande est jugée irrecevable — dont le cas « ce fichier existe déjà »
|
||||
d'une création. Les deux disent la même chose pour nous : **le sha n'est plus le
|
||||
bon**. Relire et recommencer est la bonne réponse aux deux, et elle est sans
|
||||
danger — la reprise republie avec le sha frais, donc elle n'écrase jamais rien ;
|
||||
un corps réellement mal formé échouerait de nouveau et sortirait au bout de
|
||||
trois essais, avec le texte de Gitea.
|
||||
|
||||
C'est exactement ce qu'un chemin jamais exercé cache : il était écrit, il
|
||||
compilait, il était même commenté — et il ne se déclenchait pas.
|
||||
|
||||
### Ce qui devient facultatif
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user