Search code examples
pythonpython-imaging-librarytornado

catch PIL exceptions in Tornado


Catching errors dont works partialy!

What I want to do is to detect if the user uploads real pictures or forged ones (for example a text file renamed to .jpeg).

try:
    image = Image.open(StringIO.StringIO(buf=avat))
    type = image.format
    (x, y) = image.size
    print x, y
    if x < y:
        orientation = "portrait"
    else:
        orientation = "paysage" 
    pref = str(time.time())
    nomf = pref.replace(".", "") 
    nomfich = nomf+"."+type
    self.fs = GridFS(self.db)
    avatar_id = self.fs.put(avat, content_type=avctype, filename=nomfich)
except IOError, TypeError:
    self.redirect("/erreur-im")

Here is the taceball shown in http://localhost:8000/erreur-im

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\tornado-2.3.post1-py2.7.egg\tornado\web.py", line 1023, in _execute
    getattr(self, self.request.method.lower())(*args, **kwargs)
  File "G:\Mon projet\sog-emouk\handlers.py", line 101, in get
    avctype = self.db.users.find_one()["avctype"]
TypeError: 'NoneType' object has no attribute '__getitem__'

Here, I wanted to do is redirect users to a page to tell them that the user must use image picture.

and when I've changed self.redirect to self.write("please upload....") the result was bizarre:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\tornado-2.3.post1-py2.7.egg\tornado\web.py", line 1023, in _execute
    getattr(self, self.request.method.lower())(*args, **kwargs)
  File "G:\Mon projet\sog-emouk\handlers.py", line 153, in post
    user={"pseudo":pseudo, "orientation":orientation, "avctype":avctype, "password":password, "email":email, "tel":tel, "commune":commune, "coord":coord, "statut":statut, "telf":telf, "avatar":avatar_id, "acheteur":[], "vendeur":[]}
UnboundLocalError: local variable 'orientation' referenced before assignment

So, I guess that self.redirect has something strange here since self.write excecutes the code after catching the exception (indeed the image.size is not known due to text file).`


Solution

  • This traceback suggests you are redirecting to a code that is again throwing an uncaught exception at both places. See this : avctype = self.db.users.find_one()["avctype"] and

    user={"pseudo":pseudo, "orientation":orientation, "avctype":avctype, "password":password, "email":email, "tel":tel, "commune":commune, "coord":coord, "statut":statut, "telf":telf, "avatar":avatar_id, "acheteur":[], "vendeur":[]}
    

    See both the tracebacks:

    Traceback (most recent call last):
      File "C:\Python27\lib\site-packages\tornado-2.3.post1-py2.7.egg\tornado\web.py", line 1023, in _execute
        getattr(self, self.request.method.lower())(*args, **kwargs)
      File "G:\Mon projet\sog-emouk\handlers.py", line 101, in get
        avctype = self.db.users.find_one()["avctype"]
    TypeError: 'NoneType' object has no attribute '__getitem__'
    

    and

    Traceback (most recent call last):
      File "C:\Python27\lib\site-packages\tornado-2.3.post1-py2.7.egg\tornado\web.py", line 1023, in _execute
        getattr(self, self.request.method.lower())(*args, **kwargs)
      File "G:\Mon projet\sog-emouk\handlers.py", line 153, in post
        user={"pseudo":pseudo, "orientation":orientation, "avctype":avctype, "password":password, "email":email, "tel":tel, "commune":commune, "coord":coord, "statut":statut, "telf":telf, "avatar":avatar_id, "acheteur":[], "vendeur":[]}
    UnboundLocalError: local variable 'orientation' referenced before assignment
    

    So I think you have an error in you application where you are initializing your application and request handlers.

    In addition you also have a look at how to check whether the file is actually jpeg. In fact you can check for other media file formats avi, rm etc checking the first four characters.