NameError: global name 'message' is not defined

Jose Manuel picture Jose Manuel · Feb 6, 2013 · Viewed 12.4k times · Source

I am new at python, currently I am working on a GPS tracker with that interacts with Google maps using an Arduino Uno. I am getting this error and it is not letting me run the .py script for my tcpServer this is the whole script.

#!/usr/bin/env python

import socket
import MySQLdb

TCP_IP = 'my machine IP'
TCP_PORT = 32000
BUFFER_SIZE = 40

# ClearDB. Deletes the entire tracking table

def ClearDB(curs,d ):
    curs.execute ("""
        INSERT INTO gmaptracker (lat, lon)
        VALUES (0.0,0.0)""")
    d.commit()

# Connect to the mySQL Database

def tServer():
    try:

        db = MySQLdb.connect (host = "my host",
            user = "my user",
            passwd = "my password",
            db = "gmap" )
    except MySQLdb.Error, e:
        print "Error %d: %s" %(e.args[0], e.args[1])
        sys.exit(1);

    cursor = db.cursor()

    # Start with a fresh tracking table

    ClearDB(cursor,db)

    # Set up listening Socket

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((TCP_IP, TCP_PORT))
        print "Listening...."
        s.listen(1)
        conn, addr = s.accept()
        print 'Accepted connection from address:', addr

    except socket.error (message):
        if s:
            s.close()
            print "Could not open socket: " + message
            cursor.close()
            conn.close()
            db.close()
            sys.exit(1)

    try:
        while 1:
            data = conn.recv(BUFFER_SIZE)
            if not data:break

            str1,str2 = data.split("Long: ")
            str1 = str1.split("Lat: ")[1]
            latitude = float(str1)
            longitude = float(str2)
            cursor.execute ("""
                INSERT INTO gmaptracker (lat, lon)
                VALUES (%s,%s)""", (latitude,longitude))

            db.commit()

    except KeyboardInterrupt:
        ClearDB(cursor,db);
        cursor.close()
        conn.close()
        db.close()

if __name__ == '__main__':
   tServer()

and this is the error that I am getting

Traceback (most recent call last):
 File "tcpServer.py", line 79, in <module>
   tServer()
 File "tcpServer.py", line 48, in tServer
   except socket.error(message):
NameError: global name 'message' is not defined

If anyone can help me figure this out I would greatly appreciate it, as I said I am new at python I am also running python 2.7 if that helps. Thanks in advance

Answer

Martijn Pieters picture Martijn Pieters · Feb 6, 2013

You are not using the correct syntax for catching an exception. Instead, use:

except socket.error as serror:
    message = serror.message

The socket.error exception has two extra attributes, errno and message. Older code used to catch it like this:

except socket.error, (value, message):

because in Python 2 you can treat an exception like a tuple and unpack it, but that's gone in Python 3 and should really not be used.

Moreover, the older except exceptiontype, targetvariable: has been replaced by the except exceptiontype as targetvariable: syntax as that is less ambiguous when you try to catch more than one exception type in the same statement.

When an exception is thrown, the normal flow of code is interrupted; instead the flow 'jumps' to the exception handler. Because of this jump, you have another problem in your code. In the exception handler you refer to conn.close(), but the variable conn is defined after the point where the socket exception will be thrown (the various socket operations). This will result in a NameError. In this case, there is no path through your code that'll result in conn being assigned an open socket connection, you can remove the conn.close() line altogether.

If there was a need to call .close() on conn, you'd need to detect if it was set in the first place. Set it to None, beforehand, then call .close() only if conn is no longer None:

conn = None
try:
    # ... do stuff ...
    conn, addr = s.accept()
    # ... do more stuff
except socket.error as serror:
    # test if `conn` was set
    if conn is not None:
        conn.close()