Erreur d'encodage dans un retour d'exception.

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

Je code actuellement un système de communication via le port série en python. Je me suis fais ma propre classe de com', et maintenant je m'atèle à loguer toutes les erreurs en base de donnée.

Prenons l'exemple de ma fonction de connexion :

1
2
3
4
5
6
7
8
def _Connect(self):
     try:
          #Try to connect, ...
          boResult = True
     except serial.serialutil.SerialException, err:
           self._AddStatus(self.STATUS_ERROR, self.ERROR_UNABLE_CONNECT, err.message)
           boResult = False
     return (boResult)

Si un problème survient lors de la connexion (dans la plupart des cas j'ai oublié de brancher le module), alors l'exception est levée. La fonction addStatus va se charger d'envoyer en base de donnée dans une table de log, le fait qu'un status de type erreur est survenue, que cette erreur est une erreur de type impossible de se connecter, et la raison. Le problème vient de cette dernière : la raison.

Lorsque j'affiche la raison, je vois ça :

1
2
3
4
except serial.serialutil.SerialException, err:
     print err.message # affiche -> could not open port '/dev/ttyS4': WindowsError(3, 'Le chemin d\x92acc\xe8s sp\xe9cifi\xe9 est introuvable.')
     self._AddStatus(self.STATUS_ERROR, self.ERROR_UNABLE_CONNECT, err.message)
     boResult = False

Ma page est encodée en utf-8, le coding est défini sur cet encodage aussi. Lorsque je fais un print [err.message], j'obtiens ça : ["could not open port '/dev/ttyS4': WindowsError(3, 'Le chemin d\\x92acc\\xe8s sp\\xe9cifi\\xe9 est introuvable.')"]

Les \ sont inhibés, de fait les accents ne s'affichent pas… Mais pourquoi ?

J'ai tenté milles techniques différentes, passant du .decode() et .encode() à unicode(), avec les codings les plus utilisés, jusqu'à str([e.message]).replace('\\\\', '\\') (mais non, c'est pas crade :siffle: ), mais rien n'y fait.

Quelqu'un a une idée ?

Édité par Krostar

+0 -0

C'est normal, et je crains que tu n'arrives pas à un meilleur résultat.

Quand tu affiches une liste, c'est repr qui est utilisé pour formater chacun des éléments de la liste, et en Python2, cela affiche les bytes et non les caractères.

Une question me vient à l'esprit: pourquoi chercher à l'afficher sous forme d'une liste et ne pas simplement afficher err.message ?

Auteur du sujet

Coucou entwanne,

Regarde le 2ème bout de code que j'ai posté, c'est là que j'affiche err.message, c'est là que le message s'affiche sans accent.

J'avais affiché la liste représentative de ce message uniquement pour comprendre pourquoi il m'affiche le code hexa au lieu de l'accent.

+0 -0
Auteur du sujet

Aucune idée, t'entends quoi par "j'ai la main sur la classe" ?

Si tu veux, j'utilise pySerial, j'ai refais toute une classe de com qui utilise pySerial (mais qui pourrait très bien utiliser une autre classe pour communiquer via i2c par exemple).

L'exception que je reçois quand je me connecte est levée par pySerial et je lui demande rien de plus que le message d'erreur, c'est lui et lui seul qui bosse à ce niveau là…

+0 -0
Auteur du sujet

Bon, j'ai trouvé une solution, mais elle est carrément dégueu…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
try:
    #Try to connect, ...
    boResult = True
except serial.serialutil.SerialException, err:
    arbyError = []
    err = err.message.split(': ') # j'obtiens l'erreur de pySerial d'un côté, l'erreur de windowsException de l'autre
    arbyError.append(err[0]) # j'ajoute l'erreur de pySerial à l'erreur finale
    if (len(err) > 1):
        err[1] = eval(err[1]) # j'obtiens l'objet de l'exception
        arbyError.append(str(type(err[1]))[7:-2]) # j'ajoute le nom de l'exception à l'erreur finale
        arbyError.append("err " + str(err[1].args[0])) # j'ajoute le n° d'erreur de la windows exception
        arbyError.append(err[1].args[1]) # j'ajoute l'erreur du windows exception
    err = " : ".join(arbyError).decode('cp1252') # j'obtiens une chaine d'erreur formatée comme je le veux et en unicode
    print err, type(err) # affiche Channel communication error (4) on "GPS:ser:///dev/ttyS4,,,,,100" -> could not open port '/dev/ttyS4' : exceptions.WindowsError : err 3 : Le chemin d’accès spécifié est introuvable. <type 'unicode'>
    self._AddStatus(self.STATUS_ERROR, self.ERROR_UNABLE_CONNECT, err) # elle peut désormais être loguée en bdd
    boResult = False
return (boResult)

Édité par Krostar

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte