未捕获的SyntaxError:意外的令牌{

时间:2016-01-11 22:14:24

标签: node.js stream chai

我正在尝试编写一个chai测试,其中我所做的只是流式传输一些音频并获得一个简单的响应:{},由于某种原因我在收到此错误Uncaught SyntaxError: Unexpected token {时我将fs流传输到req,如果我移除管道并且我没有那条流,那么测试工作正常。

服务器代码:

router.post('/', function (clientRequest, clientResponse) {
    clientRequest.on('end', function () {//when done streaming audio
        console.log('im at the end>>>>>');
        clientResponse.setHeader('Content-Type', 'application/json'); //I've tried removing that: same result
        clientResponse.json({});
        clientResponse.end(); //I've tried removing that: same result
    }); //end clientRequest.on('end',)
});

测试代码:

var app = require('./app');

describe('server', function() {
    this.timeout(10000);
    it('should WORK!!!"', function (done){
        var req = chai.request(app).post('/speech');

        var readStream = fs.createReadStream('./test.wav');
        readStream.on('end',function(){
            console.log("readStream end>>>>>>>>>>>>>>>>>>>>>>");
            req.end(function (err, res) {
                console.log("req.end callback>>>>>>>>>>>>>>>");
                done();
            });
        });
        readStream.pipe(req);
    });
});

错误:

Uncaught SyntaxError: Unexpected token {
     at Object.parse (native)
     at _stream_readable.js:908:16

2 个答案:

答案 0 :(得分:2)

错误分析

一般来说,代码实际上是有效的,问题出在superagent的内部。

实际上问题实际上缺少一些细节,所以我不得不猜测缺少的部分,例如chai.request(app)是使用chai-http完成的,后者又使用superagent来执行http请求。

问题似乎出现在superagent的某个地方,我能够用更多的信息重现你的错误(不知道为什么我有更长的追踪):

Uncaught SyntaxError: Unexpected token {                                                                                                                      
 at Object.parse (native)                                                                                                                                     
 at IncomingMessage.<anonymous> (/project/path/node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js:9:2
 at IncomingMessage.EventEmitter.emit (events.js:117:20)                                                                                                      
 at _stream_readable.js:920:16                                                                                                                                
 at process._tickCallback (node.js:415:13) 

我能够检查JSON解析是否尝试解析双响应。就像服务器响应{},解析器有{}{},或者服务器响应{"a":"b"}一样,解析器有{"a":"b"}{"a":"b"}。 您可以在this line之前插入console.log(res.text)来检查此问题(本地此文件位于node_modules / chai-http / node_modules / superagent下)。

此外,如果我使用readStream.pipe(req);

移动var readStream上方的var readStream = fs.createReadStream('./test.wav'); readStream.pipe(req); readStream.on('end',function(){ ...
chai-http

然后测试通过,但输出'双回调!' - 它也是printed by superagent并确认它出了问题。

修复

在没有superagentclientRequest.on('end', ...的情况下做同样的事情并不复杂。

首先,服务器端代码。它改变了一点 - 而不是var express = require('express'); var fs = require('fs'); var app = express(); module.exports = app; app.post('/speech', function (clientRequest, clientResponse) { console.log('speech'); var writeStream = fs.createWriteStream('./test_out.wav'); //for me on('end'... doesn't work (it infinitely waits for event //probably because the file is small and it finishes before we //get here clientRequest.pipe(writeStream).on('finish', function() { console.log('im at the end>>>>>'); clientResponse.json({'a':'b'}); }); }); app.listen(3000, function() { console.log("App started"); }); 我将它传递给写入流。这样我也可以检查文件是否已实际传输:

var fs = require('fs');
var chai = require('chai');
var http = require('http');

// Require our application and create a server for it
var app = require('./unexpected');
var server = http.createServer(app);
server.listen(0);
var addr = server.address();

describe('server', function() {
    this.timeout(10000);
    it('should WORK!!!"', function (done){
        // setup read stream
        var readStream = fs.createReadStream('./test.wav');
        readStream.on('end',function(){
            console.log("readStream end>>>>>>>>>>>>>>>>>>>>>>");
        });
        // setup the request
        var request = http.request({
            'host': 'localhost',
            'port': addr.port,
            'path': '/speech',
            'method': 'POST'
        });
        // now pipe the read stream to the request
        readStream.pipe(request).on('finish', function() {
            console.log("pipe end>>>>>>>>>>>>>>>>>>>>>>");
        });
        // get the response and finish when we get all the response data
        request.on('response', function(response) {
            console.log("request end>>>>>>>>>>>>>>>>>>>>>>");
            response.on('data', function(data) {
                console.log('response data: ' + data);
            });
            response.on('end', function(data) {
                console.log('done!');
                done();
            });
        });
    });
});

测试:

  $updateBlog = $c->query("UPDATE blog SET ( title, content) VALUES ('{$updateTitle}', {$postContent} ) WHERE id = {$updateID}");

我认为代码应该是不言自明的,我只是使用标准节点http module来完成这项工作。

答案 1 :(得分:0)

您可以尝试替换此命令

clientResponse.json({});

clientResponse.send({});