在Node中parsingJSON API

我正在为外部API构build一个节点包装器,并且在parsingJSON响应时遇到问题。 以下代码提出请求:

https = require "https" querystring = require "querystring" API_HOST = "api.lob.com" API_PATH = "/v1" startResponseHandler = (req, cb) -> if typeof cb isnt "function" then console.log "Error: callback needs to be a function!" req.on 'response', (res) -> response = '' res.setEncoding 'utf8' res.on 'data', (stream) -> response += stream res.on 'end', () -> error = null try response = JSON.parse response if res.statusCode != 200 or 201 response = null error = new Error response.error.message error.name = response.error.type error.code = response.error.code error.param = response.error.param catch e error = new Error "Invalid JSON" response = null cb error, response req.on 'error', (error) -> cb error module.exports = lob = (api_key) -> # This function makes the request makeRequest = (method, path, data, cb) -> data = querystring.stringify data options = hostname: API_HOST path: "#{API_PATH}/#{path}" method: method auth: "#{api_key}:" headers: 'Content-Type' : 'application/x-www-form-urlencoded' 'Content-Length' : data.length req = https.request options startResponseHandler req, cb req.write data if method is "POST" or "PUT" req.end() # GET, POST, DELETE, PUT functions _get = (path, cb) -> makeRequest "GET", path, {}, cb _post = (path, data, cb) -> makeRequest "POST", path, data, cb _del = (path, cb) -> makeRequest "DELETE", path, {}, cb _put = (path, data, cb) -> makeRequest "PUT", path, data, cb # Jobs jobs: createJob: (data, cb) -> _post "/jobs/", data, cb 

下面的代码是为了testing包装器而编写的:

 api_key = "test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc" lob = require('../src/lob')(api_key) should = require("should") chai = require("chai") data = name: "Michigan fan letter" to: "adr_43769b47aed248c2" from: "adr_7f9ece71fbca3796" object1: "obj_7ca5f80b42b6dfca" object2: "obj_12128d3aad2aa98f" describe "Job", -> @timeout(10000) describe "create", -> it "should create a job with address_id", (done) -> lob.jobs.createJob data , (new_job) -> new_job['name'].should.equal(data['name']) done() 

但是,当我运行摩卡testing( $ mocha --compilers coffee:coffee-script )时,我收到以下错误:

 1) Job create should create a job with address_id: + expected - actual +"Michigan fan letter" -"Error" 

编辑

以下是res.on 'data' stream的响应:

 { "id": "job_7ecc50bea15178b8e07a", "name": "Michigan fan letter", "price": "1.26", "to": { "id": "adr_43769b47aed248c2", "name": "Harry Zhang", "email": "harry@lob.com", "phone": "5555555555", "address_line1": "123 Test Street", "address_line2": "Unit 199", "address_city": "Mountain View", "address_state": "CA", "address_zip": "94085", "address_country": "UNITED STATES", "date_created": "2013-07-20T05:53:25+00:00", "date_modified": "2013-07-20T05:53:25+00:00", "object": "address" }, "from": { "id": "adr_7f9ece71fbca3796", "name": "Harry Zhang", "email": "harry@lob.com", "phone": "5555555555", "address_line1": "123 Test Avenue", "address_line2": "Unit 401", "address_city": "Seattle", "address_state": "WA", "address_zip": "98122", "address_country": "UNITED STATES", "date_created": "2013-07-20T05:55:19+00:00", "date_modified": "2013-07-20T05:55:19+00:00", "object": "address" }, "status": "processed", "tracking": null, "packaging": { "id": "1", "name": "Smart Packaging", "description": "Automatically determined optimal packaging for safe and secure delivery", "object": "packaging" }, "service": null, "objects": [ { "id": "obj_7ca5f80b42b6dfca", "name": "Michigan is great", "quantity": "1", "full_bleed": "0", "double_sided": "0", "date_created": "2013-07-20T05:57:32+00:00", "date_modified": "2013-07-20T05:57:32+00:00", "setting": { "id": "101", "type": "Documents", "description": "Color Document", "paper": "20lb Paper Standard", "width": "8.500", "length": "11.000", "color": "Color", "notes": "50 cents per extra page", "object": "setting" }, "url": "http://assets.lob.com/obj_7ca5f80b42b6dfca", "object": "object" }, { "id": "obj_12128d3aad2aa98f", "name": "GO BLUE", "quantity": "1", "full_bleed": "0", "double_sided": "0", "date_created": "2013-07-31T00:58:35+00:00", "date_modified": "2013-07-31T00:58:35+00:00", "setting": { "id": "100", "type": "Documents", "description": "Black and White Document", "paper": "20lb Paper Standard", "width": "8.500", "length": "11.000", "color": "Black and White", "notes": "12 cents per extra page", "object": "setting" }, "url": "http://assets.lob.com/obj_12128d3aad2aa98f", "object": "object" } ], "date_created": "2014-01-25T03:10:10+00:00", "date_modified": "2014-01-25T03:10:10+00:00", "object": "job" } 

这与文档中的示例响应完全一致

 { "id": "job_754d8b14dd31587d6873", "name": "Michigan fan letter", "price": "0.96", "to": { "id": "adr_43769b47aed248c2", "name": "Harry Zhang", "email": "harry@lob.com", "phone": "5555555555", "address_line1": "123 Test Street", "address_line2": "Unit 199", "address_city": "Mountain View", "address_state": "CA", "address_zip": "94085", "address_country": "UNITED STATES", "date_created": "2013-07-20T05:53:25+00:00", "date_modified": "2013-07-20T05:53:25+00:00", "object": "address" }, "from": { "id": "adr_7f9ece71fbca3796", "name": "Harry Zhang", "email": "harry@lob.com", "phone": "5555555555", "address_line1": "123 Test Avenue", "address_line2": "Unit 401", "address_city": "Seattle", "address_state": "WA", "address_zip": "98122", "address_country": "UNITED STATES", "date_created": "2013-07-20T05:55:19+00:00", "date_modified": "2013-07-20T05:55:19+00:00", "object": "address" }, "status": "processed", "tracking": null, "packaging": { "id": "1", "name": "Smart Packaging", "description": "Automatically determined optimal packaging for safe and secure delivery", "object": "packaging" }, "service": null, "objects": [ { "id": "obj_7ca5f80b42b6dfca", "name": "Michigan is great", "quantity": "1", "full_bleed": "0", "double_sided": "0", "date_created": "2013-07-20T05:57:32+00:00", "date_modified": "2013-07-20T05:57:32+00:00", "setting": { "id": "101", "type": "Documents", "description": "Color Document", "paper": "20lb Paper Standard", "width": "8.500", "length": "11.000", "color": "Color", "notes": "50 cents per extra page", "object": "setting" }, "object": "object" } ], "date_created": "2014-01-18T19:52:27+00:00", "date_modified": "2014-01-18T19:52:27+00:00", "object": "job" } 

这里是来自JSON.parse response的数据

 { id: 'job_9973e060bd8147f97f5f', name: 'Michigan fan letter', price: '1.26', to: { id: 'adr_43769b47aed248c2', name: 'Harry Zhang', email: 'harry@lob.com', phone: '5555555555', address_line1: '123 Test Street', address_line2: 'Unit 199', address_city: 'Mountain View', address_state: 'CA', address_zip: '94085', address_country: 'UNITED STATES', date_created: '2013-07-20T05:53:25+00:00', date_modified: '2013-07-20T05:53:25+00:00', object: 'address' }, from: { id: 'adr_7f9ece71fbca3796', name: 'Harry Zhang', email: 'harry@lob.com', phone: '5555555555', address_line1: '123 Test Avenue', address_line2: 'Unit 401', address_city: 'Seattle', address_state: 'WA', address_zip: '98122', address_country: 'UNITED STATES', date_created: '2013-07-20T05:55:19+00:00', date_modified: '2013-07-20T05:55:19+00:00', object: 'address' }, status: 'processed', tracking: null, packaging: { id: '1', name: 'Smart Packaging', description: 'Automatically determined optimal packaging for safe and secure delivery', object: 'packaging' }, service: null, objects: [ { id: 'obj_7ca5f80b42b6dfca', name: 'Michigan is great', quantity: '1', full_bleed: '0', double_sided: '0', date_created: '2013-07-20T05:57:32+00:00', date_modified: '2013-07-20T05:57:32+00:00', setting: [Object], url: 'http://assets.lob.com/obj_7ca5f80b42b6dfca', object: 'object' }, { id: 'obj_12128d3aad2aa98f', name: 'GO BLUE', quantity: '1', full_bleed: '0', double_sided: '0', date_created: '2013-07-31T00:58:35+00:00', date_modified: '2013-07-31T00:58:35+00:00', setting: [Object], url: 'http://assets.lob.com/obj_12128d3aad2aa98f', object: 'object' } ], date_created: '2014-01-25T23:12:37+00:00', date_modified: '2014-01-25T23:12:37+00:00', object: 'job' } 

我在代码中看到三个问题。 我通常不使用CoffeeScript。 所以如果我误读,请纠正我:

  1. callback是这样调用的:

     cb error, response 

    第一个参数是一个错误对象,第二个参数是响应,但在testing中,callback是这样的:

     lob.jobs.createJob data , (new_job) -> new_job['name'].should.equal(data['name']) 

    所以new_job是错误对象。 然而,这并不能解释所有的事情,因为你正在得到一个错误。 但即使没有错误, new_job的值也不会是响应。

    testing显示stringError是实际值的原因是Error对象有一个name字段,它被设置为exception类的名称。 (所以new Error().name计算结果为"Error"

  2. 这段代码也看起来不正确:

     try response = JSON.parse response if res.statusCode != 200 or 201 response = null error = new Error response.error.message error.name = response.error.type error.code = response.error.code error.param = response.error.param catch e error = new Error "Invalid JSON" response = null cb error, response 

    if分支中, response被设置为null ,然后访问一些response字段。 这将导致一个exception。 而这个exception将被解释为不好的JSON,因为try... catch子句的设置方式。 try... catch子句应该缩小到仅包含JSON.parse调用:

     try response = JSON.parse response catch e error = new Error "Invalid JSON" response = null 
  3. 这个testing是不正确的:

      if res.statusCode != 200 or 201 

    它变成了JavaScript:

      if (res.statusCode !== 200 || 201) 

    ||之后的部分 使其始终如此。 像下面的CoffeeScript代码似乎是什么意图:

      if res.statusCode not in [200, 201] 

所以请求是否成功并不重要。 由于第三个问题, iftesting将始终为真,分支将始终被采用,第二个问题将始终发生。 所以摩卡testing总是会失败。