Json响应错误:响应为空?

时间:2013-02-22 10:59:42

标签: python json error-handling tornado uncaught-exception

我有一个问题。

我有一个页面,我将命令发送到传感器网络。

当我点击这部分代码时

<a href='javascript:void(send_command_to_sensor("{{net.id}}", "{{sens.id}}", "identify"));'></a>

我调用js函数,这个:

function send_command_to_sensor(net, sens, command) {
  $.ajax({url: "/networks/" + net + "/sensors/" + sens + "/send?command=" + command,
  type: "GET",
  async: true,
  dataType: "json",
  success: function(json_response) { 
             var err = json_response['error'];
         if (err) {
           show_alert('error', err);
           return;
         }
         var success = json_response['success'];
         if (success) {
           show_alert('success', success);
           return;
         }
         show_alert('alert', "This should not happen!");
           }
  }); 
}

此函数构建一个url,用于调用用python编写的Tornado Web服务器中的处理程序。处理程序是这样的:

################################################################################
# SensorSend handler. 
# Sends a packet to the sensor by writing in a file (Should work through
# MySQL database) read by Quantaserv Daemon
################################################################################
class SensorSendHandler(BaseHandler):
    # Requires authentication 
    @tornado.web.authenticated
    def get(self, nid, sid):
        command = self.get_argument('command').upper(); 

        print command

        # Retrieve the current user 
        usr = self.get_current_user()
        usr_id = usr['id']

        self.lock_tables("read", ['nets_permissions as n'])
        perm = self.db.get("SELECT n.perm FROM nets_permissions as n \
                              WHERE n.network_id=%s AND n.user_id=%s", nid, int(usr_id))
        self.unlock_tables()

        # Check whether the user has access to the network
        perms = self.check_network_access(nid, perm['perm'])

        #Check wether the sensor exists in this network
        self.check_sensor_in_network(sid, nid)

        # The dictionary to return
        ret = {}

        ############################################################################
        # The following Code is valid for ZTC networks only
        # Must be generalized
        # TODO: - get the network type:
        #       - check wether the command is allowed
        ############################################################################
        if command not in ['ON', 'OFF', 'TOGGLE', 'IDENTIFY']:
            raise tornado.web.HTTPError(404, "Unknown command: " + str(command))


        #Command OnOffCmd_SetState
        if command in ['ON', 'OFF', 'TOGGLE']:
            op_group = "70"
            op_code = "50"
            packet_meta = "%s%s%s%s02%s%s600080000%s"
            pkt_len = hextransform(16, 2)
            netid = hextransform(int(nid), 16)
            sens_id = hextransform(int(sid) >> 16, 4)
            sens_id_little = invert2bytes(sens_id,0)
            cluster_id = hextransform(int(sid) & 0x00FFFF, 4)
            end_point = "08"


            if command == 'ON':
                cmd_data = "01"
            elif command == 'OFF':
                cmd_data = "00"
            elif command == 'TOGGLE':
                cmd_data = "02"

            packet = packet_meta % (netid, op_group, op_code, pkt_len, sens_id, end_point, cmd_data)
            packet = packet.upper()

            op_group_hex=0x70
            op_code_hex=0x50

            print command

        #Command ZDP-IEEE_addr.Request            
        elif command == 'IDENTIFY':
            op_group = "A2"
            op_code = "01"
            packet_meta = "%s%s%s%s"
            pkt_len = hextransform(2, 2)

            sens_id = hextransform(int(sid) >> 16, 4)
            sens_id_little = invert2bytes(sens_id,0)

            packet = packet_meta % (op_group, op_code, pkt_len, sens_id)
            packet = packet.upper()

            op_group_hex=0xA2
            op_code_hex=0x01


        #Command ZDP-Active_EP_req.Request            
        elif command == 'HOWMANY':
            op_group = "A2"
            op_code = "05"
            packet_meta = "%s%s%s%s%s"
            pkt_len = hextransform(4, 2)
            netid = hextransform(int(nid), 16)
            sens_id = hextransform(int(sid) >> 16, 4)
            sens_id_little = invert2bytes(sens_id,0)

            packet = packet_meta % (op_group, op_code, pkt_len, sens_id, netid)
            packet = packet.upper()

            op_group_hex=0xA2
            op_code_hex=0x05



        mynet_type ="ztc"

        cmdjson = packet2json(op_group_hex,op_code_hex, packet)

        print("\t\t " + packet + "\n")

        #
        #
        #TODO : -write command into db  
        ts = datetime.datetime.now().isoformat()
        self.lock_tables("write", ['confcommands'])
        self.db.execute("INSERT INTO confcommands (network_id, ntype, timestamp, command) \
                                  VALUES (%s,%s,%s,%s)", nid, mynet_type, ts, cmdjson)
        self.unlock_tables();
        ############### ELISA ##########################################
        # TODO: - open the /tmp/iztc file in append mode
        cmdfile = open('/tmp/iztc', 'a')
        #       - acquire a lock  "only for the DB case, it's easier"
        #       - write the packet 
        cmdfile.write(nid + "\t"+ mynet_type + "\t"+ ts + "\t"+  cmdjson +"\n");
        #       - release the lock "only for the DB case, it's easier"
        #       - close the file
        cmdfile.close()


        if command == 'HOWMANY':
            opcodegroupr = "A0"
            opcoder = "85"
        elif command == 'IDENTIFY':
            opcodegroupr = "A0"
            opcoder = "81"

        print command

        #Code for retrieving the MAC address of the node
        como_url = "".join(['http://', options.como_address, ':', options.como_port,
                            '/', ztc_config, '?netid=', netid,
                            '&opcode_group=', opcodegroupr, 
                            '&opcode=', opcoder, '&start=-5m&end=-1s'])
        http_client = AsyncHTTPClient()
        response = yield tornado.gen.Task(http_client.fetch, como_url)

        ret = {}
        if response.error:
            ret['error'] = 'Error while retrieving unregistered sensors'
        else:
            for line in response.body.split("\n"):
                if line != "": 
                    value = int(line.split(" ")[6])

        ret['response'] = value
        self.write(tornado.escape.json_encode(ret))


        if command == 'HOWMANY':
            status = value[0]
            NwkAddress = value[1:2]
            ActiveEPCount = value[3]
            ActiveEPList = value[len(ActiveEPCount)]
            if status == "0":
                ret['success'] = "The %s command has been succesfully sent!" % (command.upper())
                self.write(tornado.escape.json_encode(ret))
            elif status == "80":
                ret['error'] = "Invalid Request Type"
                self.write(tornado.escape.json_encode(ret))
            elif status == "89":
                ret['error'] = "No Descriptor"
                self.write(tornado.escape.json_encode(ret))
            else:
                ret['error'] = "Device not found!"
                self.write(tornado.escape.json_encode(ret))


        if command == 'IDENTIFY':
            status = value[0]
            IEEEAddrRemoteDev = value[1:8]
            NWKAddrRemoteDev = value[9:2]
            NumOfAssociatedDevice = value[11:1]
            StartIndex = value[12:1]
            ListOfShortAddress = value[13:2*NumOfAssociatedDevice]
            if status == "0":
                ret['success'] = "Command succesfully sent! The IEEE address is: %s" % (IEEEAddrRemoteDev)
                self.write(tornado.escape.json_encode(ret))
            elif status == "80":
                ret['success'] = "Invalid Request Type"
                self.write(tornado.escape.json_encode(ret))
            else:
                ret['error'] = "Device Not Found"
                self.write(tornado.escape.json_encode(ret))

我在开发者consolle中收到的错误是:

  

未捕获的TypeError:无法读取null的属性'error'   $ .ajax.successwsn.js:26 jQuery.Callbacks.firejquery-1.7.2.js:1075   jQuery.Callbacks.self.fireWithjquery-1.7.2.js:1193   donejquery-1.7.2.js:7538 jQuery.ajaxTransport.send.callback

在js函数中。为什么功能不知道'错误'或'成功'?问题出在哪儿????我认为程序不会在处理程序中输入,而是在js函数之后被阻塞。

非常感谢您的帮助!这是一个很长的帖子,但它很容易阅读!请!

1 个答案:

答案 0 :(得分:1)

快速阅读是功能未正确装饰。

该行

 response = yield tornado.gen.Task(http_client.fetch, como_url)

意味着你应该如此声明这个功能:

@tornado.web.asynchronous
@tornado.gen.engine
@tornado.web.authenticated
def get(self):
    ....

请注意添加两个额外的装饰器。