Projet

Général

Profil

Bug #55793

Caluire Axel : crash lingo

Ajouté par Nicolas Roche il y a plus de 2 ans. Mis à jour il y a plus de 2 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
23 juillet 2021
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Traceback:

File "/usr/lib/python3/dist-packages/passerelle/utils/jsonresponse.py" in api
  128.             resp = f(*args, **kwargs)

File "/usr/lib/python3/dist-packages/passerelle/views.py" in perform
  527.         result = self.endpoint(request, **params)

File "/usr/lib/python3/dist-packages/passerelle/contrib/caluire_axel/models.py" in pay_invoice
  1220.         code = result.json_response['DATA']['PORTAIL']['SETPAIEMENT']['CODE']

Exception Type: TypeError at /caluire-axel/axel/regie/ENF/invoice/16526-319992/pay/
Exception Value: 'NoneType' object is not subscriptable

Fichiers


Demandes liées

Lié à Combo - Development #55876: lingo : créer le BasketItem représentant le paiement d'une facture quand elle est payée, pas quand l'application est notifiéeFermé27 juillet 2021

Actions

Révisions associées

Révision b7059464 (diff)
Ajouté par Nicolas Roche il y a plus de 2 ans

caluire-axel: handle wrong messages on pay_invoice (#55793)

Historique

#1

Mis à jour par Nicolas Roche il y a plus de 2 ans

Dans les logs du connecteur, l'erreur indique (dans le payload) un numéro de transaction :

body     b'{"transaction_id": "bbd90fe0-eb83-11eb-bb4a-0213ad91a103", "transaction_date": "2021-07-23T07:02:11"}'
method     POST
exception     'NoneType' object is not subscriptable

#2

Mis à jour par Nicolas Roche il y a plus de 2 ans

La facture concernée :

{
   "data" : {
      "amount" : "2.6",
      "amount_paid" : "0",
      "created" : "2020-02-10",
      "display_id" : "319992",
      "has_pdf" : true,
      "id" : "16526-319992",
      "label" : "Facture unique - Janvier 2020",
      "online_payment" : true,
      "paid" : false,
      "pay_limit_date" : "2020-02-28",
      "total_amount" : "2.6",
      "vendor" : {
         "caluire-axel" : {
            "ECHEANCE" : "2020-02-28",
            "EMISSION" : "2020-02-10",
            "ENCAISSE" : "0",
            "EXISTEPDF" : true,
            "FACTURATION" : "Facture unique - Janvier 2020",
            "IDFACTURE" : 319992,
            "MONTANT" : "2.6" 
         }
      }
   },
   "err" : 0
}

#4

Mis à jour par Nicolas Roche il y a plus de 2 ans

Axel, qui nous présente cette facture à payer (via GETFACTURESAPAYER), nous renvoie un contenu vide (<PORTAIL/>).
Partant principe que le statut de la réponse est OK (<STATUS>OK</STATUS>) ce contenu aurait du se conformer au schéma R_SetPaiement.xsd et retourner code (0 Ok Négatif sinon dixit la doc).

<?xml version="1.0" encoding="UTF-8"?>
<PORTAILSERVICE>
  <RESULTAT>
    <TYPE>SetPaiement</TYPE>
    <STATUS>OK</STATUS>
    <DATE>23/07/2021 15:44:17</DATE>
    <COMMENTAIRES><![CDATA[]]></COMMENTAIRES>
  </RESULTAT>
  <DATA>
    <PORTAIL/>
  </DATA>
</PORTAILSERVICE>

#5

Mis à jour par Nicolas Roche il y a plus de 2 ans

  • Statut changé de Nouveau à Fermé

Je ferme ici car la cause première est qu'il s'agit d'une facture payée après sa date d'échéance
(Il n'y a pas d'erreur dans le code du connecteur).

Il restera néanmoins à corriger les données sur l'instance calluire (ticket projet).

#7

Mis à jour par Benjamin Dauvergne il y a plus de 2 ans

  • Statut changé de Fermé à Nouveau

Bah si y a un bug dans le connecteur. Au minimum il ne faudrait pas tracer, si Axel peut retourner un truc, vide il faut le détecter et retourner un message d'erreur "facture qui n'existe plus/payée hors échéance" et aussi pourquoi cette facture a pu être payée si elle est hors échéance ? Elle n'aurait jamais du être retournée (ou alors c'est un cas limite payé au moment de la limite et donc ma première réponse est bonne faut une erreur claire sur le problème et dans le workflow passer en mode "récupération manuelle cas paiement hors date limite").

#8

Mis à jour par Benjamin Dauvergne il y a plus de 2 ans

Il faut mettre online_payment à False ou alors ne pas retourner la facture hors historique.

#9

Mis à jour par Nicolas Roche il y a plus de 2 ans

Il faut mettre online_payment à False

Désolé, je ne comprend pas.
Je reformule : Axel dit voilà ce qu'il faut payer, Lingo lui dit "voilà c'est fait" et Axel qui devrait dire "ok" ou "erreur" renvoie un message non conforme aux specs.

On est sur un crach du endpoit /caluire-axel/axel/regie/ENF/invoice/16526-319992/pay/
qui est appelé par lingo sans qu'ensuite aucune attention ne soit acordée contenu retourné.

regie.pay_invoice(item_id, self.order_id, self.bank_transaction_date or self.end_date)

Si l'on ne crash pas, alors l'appel ne sera plus retenté et la transaction ne sera plus vue comme orpheline (au sens de la note #3) alors que l'on ne sait pas si elle a bien été prise en compte ou non par le logiciel métier.

edit:
Désolé j'ai été embrouillé par https://dev.entrouvert.org/issues/55793#note-8 qui a plutôt rapport avec #55803.
Et donc oui, renvoyer une erreur qui donne du contexte plutôt que de crasher.

#10

Mis à jour par Nicolas Roche il y a plus de 2 ans

#11

Mis à jour par Frédéric Péters il y a plus de 2 ans

Je taperais plus large, façon

-        code = result.json_response['DATA']['PORTAIL']['SETPAIEMENT']['CODE']
+        try:
+            code = int(result.json_response['DATA']['PORTAIL']['SETPAIEMENT']['CODE'])
+        except (KeyError, ValueError):
+            raise APIError('Wrong pay-invoice response', err_code='pay-invoice-code-response-error')
+
         if code < 0:
             raise APIError('Wrong pay-invoice status', err_code='pay-invoice-code-error-%s' % code)

(de ton patch il y a aussi l'ajout d'une partie "data" à l'erreur, sur ce moment particulier, mais pas sur l'APIError qui peut être levée trois lignes plus bas, je n'ai pas repris ça dans mon exemple).

#13

Mis à jour par Thomas Noël il y a plus de 2 ans

Oui pour ajouter du data pour avoir le contexte dans l'APIError, mais que va-t-il devenir (où va-t-on pouvoir le voir afin de comprendre la panne) ?

Par ailleurs sur le premier data, j'ajouterais "post_data": post_data, et j'appelerais kwargs avec son vrai nom "kwargs": kwargs au lieu de payload, qui pourrait laisser croire que c'est ce qu'on a envoyé à Axel.

Dans le second data, j'ajouterais "result": result.json_response pour voir ce qui ne va pas dedans

#19

Mis à jour par Nicolas Roche il y a plus de 2 ans

Nicolas tu peux creuser le chemin que prend l'ApiError...

Je dirais que si on sort en 500 on l'aura encore dans les traces envoyées par mail.

Pour moi il faudrait qu'on ne soit pas alerté en cas de crash
complet de Axel (lingo retentera chaque heure) mais qu'on le soit en
cas d'erreur incohérente (le second ApiError).

J'ai mis un code 500 sur la deuxième exception

Et que dans les deux cas, ça soit visible dans les journaux de transaction de lingo.

c'est bien prévu :

# 5xx, err or requests error
to_be_paid_remote_items.append(item_id)
logger.warning(
    'unable to notify payment for remote item %s from transaction %s, retry later',
    item_id,
    self,
)

$ ssh grandlyon-guichet-prod-1
$ sudo journalctl TENANT="ville-caluire.toodego.com" | grep 'unable to notify payment'
juil. 27 08:20:36 eddv-gdlyon-gnm-front-1.synaaps.local /usr/lib/combo/manage.py[19282]: combo WARNING ville-caluire.toodego.com - - - unable to notify payment for remote item 16526-319992 from transaction Transaction object (92), retry later

Quand à la résolution du paiement, je doute qu'Axel nous renvoie une réponse un jour
(ici https://dev.entrouvert.org/issues/55799#note-2 on voit qu'Axel ne veut pas accépter l'information comme quoi la facture a été payée).
Pourtant, puisque la facture a bien été payée en ligne, je pense qu'il faut la rattacher à la main à la transaction pour qu'elle apparaisse en visuel ici :
https://ville-caluire.toodego.com/manage/lingo/?q=bbd90fe0-eb83-11eb-bb4a-0213ad91a103

#20

Mis à jour par Benjamin Dauvergne il y a plus de 2 ans

Nicolas Roche a écrit :

Pourtant, puisque la facture a bien été payée en ligne, je pense qu'il faut la rattacher à la main à la transaction pour qu'elle apparaisse en visuel ici :
https://ville-caluire.toodego.com/manage/lingo/?q=bbd90fe0-eb83-11eb-bb4a-0213ad91a103

Oui ça c'est un souci lingo, on ne crée le BasketItem lié à une facture que lorsque sont paiement a été notifié1, on devrait le créer dès le retour de la banque, qu'on arrive pas à notifier l'application métier ça ne concerne pas l'usager.

Je viens de créer #55876 sur le sujet.

#21

Mis à jour par Nicolas Roche il y a plus de 2 ans

Je déporte la création du BasketItem manquant lié à cette facture dans #55877.
Et ici, je re-dépose le même patch, mais qui ne mange pas de ligne.

#22

Mis à jour par Benjamin Dauvergne il y a plus de 2 ans

  • Statut changé de Solution proposée à Solution validée
#23

Mis à jour par Nicolas Roche il y a plus de 2 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit b70594644a262182b667139dfbc285b4f6dc4a22
Author: Nicolas ROCHE <nroche@entrouvert.com>
Date:   Fri Jul 23 18:45:12 2021 +0200

    caluire-axel: handle wrong messages on pay_invoice (#55793)
#24

Mis à jour par Benjamin Dauvergne il y a plus de 2 ans

  • Lié à Development #55876: lingo : créer le BasketItem représentant le paiement d'une facture quand elle est payée, pas quand l'application est notifiée ajouté
#25

Mis à jour par Frédéric Péters il y a plus de 2 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF