{"action":"created","issue":{"url":"https://api.github.com/repos/jsreport/nodejs-client/issues/1","labels_url":"https://api.github.com/repos/jsreport/nodejs-client/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/jsreport/nodejs-client/issues/1/comments","events_url":"https://api.github.com/repos/jsreport/nodejs-client/issues/1/events","html_url":"https://github.com/jsreport/nodejs-client/issues/1","id":102903756,"number":1,"title":"sometimes the response is incorrect (malformed or incomplete) when using phantom-pdf recipe","user":{"login":"bjrmatos","id":4262050,"avatar_url":"https://avatars.githubusercontent.com/u/4262050?v=3","gravatar_id":"","url":"https://api.github.com/users/bjrmatos","html_url":"https://github.com/bjrmatos","followers_url":"https://api.github.com/users/bjrmatos/followers","following_url":"https://api.github.com/users/bjrmatos/following{/other_user}","gists_url":"https://api.github.com/users/bjrmatos/gists{/gist_id}","starred_url":"https://api.github.com/users/bjrmatos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjrmatos/subscriptions","organizations_url":"https://api.github.com/users/bjrmatos/orgs","repos_url":"https://api.github.com/users/bjrmatos/repos","events_url":"https://api.github.com/users/bjrmatos/events{/privacy}","received_events_url":"https://api.github.com/users/bjrmatos/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-08-24T22:19:04Z","updated_at":"2015-08-25T09:22:57Z","closed_at":null,"body":"Hi @pofider i'm encountering a weird issue when rendering a report with the jsreport-client\r\n\r\nsometimes the buffer returned from the jsreport-client arrives incomplete causing an invalid pdf (seems like a bug with `concat-stream`)\r\n\r\nin order to detect this behaviour, i needed to compare the size of the buffer returned by jsreport and jsreport-client\r\n\r\ni have added in jsreport's codebase a log to know the size of the returned buffer\r\n\r\n(jsreport/lib/reporter.js line 187)\r\n\r\n```js\r\nreturn q.ninvoke(this.toner, \"render\", request).then(function (response) {\r\n        self.logger.info(\"Rendering request \" + request.reportCounter + \" finished in \" + (new Date() - request.startTime) + \" ms\");\r\n        response.result = response.stream;\r\n        \r\n        /* NEW CODE TO LOG AND SAVE PDF GENERATION */\r\n        console.log('jsreport response buffer length:', response.content.length);\r\n        // save the pdf to inspect later\r\n        fs.writeFile('C:\\\\xampp\\\\htdocs\\\\facturactiva\\\\issuer-integration-api\\\\dist\\\\from-jsreport.pdf', response.content);\r\n        /* END NEW CODE */\r\n\r\n        return response;\r\n    }).catch(function (e) {\r\n        e.message = \"Error during rendering report: \" + e.message;\r\n        var logFn = e.weak ? self.logger.warn : self.logger.error;\r\n        logFn(\"Error when processing render request \" + e.message + \" \" + e.stack);\r\n        throw e;\r\n    });\r\n```\r\n\r\nthis is my code using jsreport-client (with the log of the returned buffer from jsreport-client):\r\n\r\n```js\r\nvar reportClient = jsReportClient(REPORT_SERVER_URL, REPORT_SERVER_USER, REPORT_SERVER_PWD);\r\n\r\nvar asyncPDFRender = new Promise(function(resolve, reject) {\r\n  reportClient.render({\r\n    template: {\r\n      shortid: 'VkNparuL',\r\n      recipe: 'phantom-pdf'\r\n    },\r\n    data: {  ..my data here..  }\r\n  }, function(err, reportResponse) {\r\n    if (err) {\r\n      return reject(new Error('error when trying to render PDF'));\r\n    }\r\n\r\n    resolve(reportResponse);\r\n  });\r\n});\r\n\r\nasyncPDFRender.then(function(report) {\r\n  return new Promise(function(resolve, reject) {\r\n    report.body(function(reportBody) {\r\n      /** LOG **/\r\n      console.log('jsreport-client response buffer length:', reportBody.length);\r\n\r\n      console.log('jsreport-client response is correct:', reportBody.length === 27776);\r\n\r\n      /** END LOG **/\r\n\r\n      resolve(writeFileAsync(path.join(__dirname, 'dist', 'report.pdf'), reportBody));\r\n    });\r\n  });\r\n}).then(function() {\r\n  console.log('Reporte generado en PDF!');\r\n}).catch(function(err) {\r\n  console.error('Error:', err);\r\n});\r\n\r\n```\r\n\r\ntest:\r\n\r\n![fail](https://cloud.githubusercontent.com/assets/4262050/9453507/6ff6b514-4a80-11e5-8f1b-57a4cd9d01f1.gif)\r\n\r\n\r\nas you can see, sometimes the response is different (buffer size: 19590) compared to the original response from jsreport (buffer size: 27776)\r\n\r\ni have modified jsreport-client's codebase to return the buffer from request's (the module) callback instead of the buffer returned by `concat-stream`\r\n\r\n(jsreport-client/lib/client.js line 38)\r\n\r\n```js\r\n   if (this.username) {\r\n        requestOptions.auth = {\r\n            username: this.username,\r\n            password: this.password\r\n        }\r\n    }\r\n    \r\n    // var responseStream = request.post(requestOptions);\r\n\r\n    // responseStream.on(\"error\", function(err) {\r\n    //     cb(err);\r\n    // });\r\n\r\n    // responseStream.on(\"response\", function (response) {\r\n    //     if (response.statusCode !== 200) {\r\n    //         return responseToBuffer(response, function(data) {\r\n    //             try {\r\n    //                 var errorMessage = JSON.parse(data.toString());\r\n    //                 var error = new Error(errorMessage.message);\r\n    //                 error.remoteStack = errorMessage.stack;\r\n    //                 cb(error)\r\n    //             }\r\n    //             catch(e) {\r\n    //                 cb(new Error(data));\r\n    //             }\r\n    //         });\r\n    //     }\r\n\r\n    //     response.body = function(cb) { responseToBuffer(response, cb); }\r\n    //     cb(null, response);\r\n    // });\r\n\r\n    /* MODIFIED CODE */\r\n    request.post(requestOptions, function(err, httResp, body) {\r\n      if (err) {\r\n        var error = new Error(err.message);\r\n        error.remoteStack = errorMessage.stack;\r\n        return cb(error);\r\n      }\r\n\r\n      cb(null, body);\r\n    });\r\n    /* END MODIFIED CODE */\r\n```\r\n\r\nwith this change the result is correct, it never gets corrupted i have tested several times (note that in the change i'm not returning a response object, only the buffer, just in order to test quickly):\r\n\r\n![win](https://cloud.githubusercontent.com/assets/4262050/9453993/27d02b86-4a84-11e5-9229-1f04332f203c.gif)\r\n\r\npreview of `report.pdf` (invalid pdf)\r\n\r\n![image](https://cloud.githubusercontent.com/assets/4262050/9453357/84346cca-4a7f-11e5-8211-37387331a60c.png)\r\n\r\n\r\npreview of `from-jsreport.pdf` \r\n\r\n![image](https://cloud.githubusercontent.com/assets/4262050/9453384/b56520d2-4a7f-11e5-8777-214e5d6c6d06.png)\r\n\r\n\r\n**i'm using:**\r\n**jsreport = 1.7.2**\r\n**node = 0.10.40**\r\n**(jsreport) nodejs-client = 0.3.0 (last version)**"},"comment":{"url":"https://api.github.com/repos/jsreport/nodejs-client/issues/comments/134537656","html_url":"https://github.com/jsreport/nodejs-client/issues/1#issuecomment-134537656","issue_url":"https://api.github.com/repos/jsreport/nodejs-client/issues/1","id":134537656,"user":{"login":"pofider","id":2041960,"avatar_url":"https://avatars.githubusercontent.com/u/2041960?v=3","gravatar_id":"","url":"https://api.github.com/users/pofider","html_url":"https://github.com/pofider","followers_url":"https://api.github.com/users/pofider/followers","following_url":"https://api.github.com/users/pofider/following{/other_user}","gists_url":"https://api.github.com/users/pofider/gists{/gist_id}","starred_url":"https://api.github.com/users/pofider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pofider/subscriptions","organizations_url":"https://api.github.com/users/pofider/orgs","repos_url":"https://api.github.com/users/pofider/repos","events_url":"https://api.github.com/users/pofider/events{/privacy}","received_events_url":"https://api.github.com/users/pofider/received_events","type":"User","site_admin":false},"created_at":"2015-08-25T09:22:57Z","updated_at":"2015-08-25T09:22:57Z","body":"Wow, what a bug report!\r\n\r\nThe problem with your fix is that you are then loading always the whole pdf into the memory. This is unwanted and that is why I don't let request module to load the output into the body. You can easily pipe the response stream to the file without parsing the body. That would probably also solve your issue.\r\n```js\r\nreportClient.render({...}, function(err, resp) {\r\n  var fs = require('fs'); \r\n  var wstream = fs.createWriteStream('myOutput.pdf');\r\n  resp.pipe(wstream);\r\n}\r\n```\r\n\r\nHowever it should also work with the buffers, but unfortunately I was not able to reproduce your issue on the same versions with hundreds of reports. Anyway I tried to remove `concat-stream` and replaced it with the same reading technique as in request module. Could you please try to replace the following method and try it?\r\n```js\r\n//client.js\r\n//install bl module first\r\nfunction responseToBuffer(response, cb) {\r\n    var buffer = require(\"bl\")();\r\n    response.on(\"data\", function(chunk) {\r\n        buffer.append(chunk)\r\n    });\r\n\r\n    response.on(\"end\", function() {\r\n        cb(buffer.slice());\r\n    });\r\n}\r\n```"}}