SyntaxError no detectada: fichas inesperado {

Estoy tratando de escribir una prueba de chai en la que todo lo que hago es transmitir un poco de audio y obtener una respuesta simple: {} , por alguna razón, estoy recibiendo este error Uncaught SyntaxError: Unexpected token { siempre que Uncaught SyntaxError: Unexpected token { mi flujo de fs a req , si quito la tubería y no tengo esa stream, la prueba funciona bien.

código de servidor:

 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',) }); 

código de prueba:

 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); }); }); 

error:

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

Análisis de errores

El código en general funciona realmente y el problema está en algún lugar dentro del superagente.

En realidad, en la pregunta faltan algunos detalles, por lo que tuve que adivinar las partes faltantes, como chai.request(app) se hace usando chai-http , que a su vez usa superagente para realizar solicitudes http.

Y el problema parece estar en algún lugar dentro del superagente, pude reproducir tu error con un poco más de información (no estoy seguro de por qué obtuve un seguimiento más largo):

 Uncaught SyntaxError: Unexpected token { at Object.parse (native) at IncomingMessage. (/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) 

Y pude comprobar que JSON analiza los bashs de analizar la respuesta doble. Al igual que si el servidor responde con {} , el analizador tiene {}{} , o si el servidor responde con {"a":"b"} , el analizador tiene {"a":"b"}{"a":"b"} . Puede comprobarlo usted mismo insertando console.log(res.text) antes de esta línea (localmente, este archivo se encuentra en node_modules / chai-http / node_modules / superagent).

También si muevo el readStream.pipe(req); justo encima de la línea con var readStream :

 var readStream = fs.createReadStream('./test.wav'); readStream.pipe(req); readStream.on('end',function(){ ... 

Luego pasa la prueba, pero da como resultado ‘doble callback’ – También está impreso por superagente y confirma que algo va mal con él.

La solución

No es complejo hacer lo mismo sin chai-http y superagent .

Primero, el código del lado del servidor. Se modificó un poco, en lugar de clientRequest.on('end', ... Lo clientRequest.on('end', ... a la secuencia de escritura. De esta forma también puedo verificar que el archivo se haya transferido realmente:

 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"); }); 

Y la prueba:

 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(); }); }); }); }); 

Creo que el código debe explicarse por sí mismo, solo uso el módulo http de nodo estándar para hacer el trabajo.

puede intentar reemplazar este comando

 clientResponse.json({}); 

con

 clientResponse.send({});