{"action":"created","issue":{"url":"https://api.github.com/repos/visionmedia/superagent/issues/852","labels_url":"https://api.github.com/repos/visionmedia/superagent/issues/852/labels{/name}","comments_url":"https://api.github.com/repos/visionmedia/superagent/issues/852/comments","events_url":"https://api.github.com/repos/visionmedia/superagent/issues/852/events","html_url":"https://github.com/visionmedia/superagent/issues/852","id":126775983,"number":852,"title":"Fake Promise is a breaking API change","user":{"login":"rooftopsparrow","id":853349,"avatar_url":"https://avatars.githubusercontent.com/u/853349?v=3","gravatar_id":"","url":"https://api.github.com/users/rooftopsparrow","html_url":"https://github.com/rooftopsparrow","followers_url":"https://api.github.com/users/rooftopsparrow/followers","following_url":"https://api.github.com/users/rooftopsparrow/following{/other_user}","gists_url":"https://api.github.com/users/rooftopsparrow/gists{/gist_id}","starred_url":"https://api.github.com/users/rooftopsparrow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rooftopsparrow/subscriptions","organizations_url":"https://api.github.com/users/rooftopsparrow/orgs","repos_url":"https://api.github.com/users/rooftopsparrow/repos","events_url":"https://api.github.com/users/rooftopsparrow/events{/privacy}","received_events_url":"https://api.github.com/users/rooftopsparrow/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-01-14T23:54:23Z","updated_at":"2016-01-15T15:26:31Z","closed_at":null,"body":"The fake promise that was introduced in #709 is a **BREAKING** change and not backwards compatible.\r\n\r\nI wrote a little scenario involving an async action via a promise. Before this change was made, this was perfectly valid until the fake promise was added to the library. For this scenario, I used native promises but have also tested with a promise library with the same result.\r\n\r\n```js\r\nvar http = require('http')\r\nvar fs = require('fs')\r\nvar superagent = require('superagent')\r\nvar dest = fs.createWriteStream('response.txt')\r\n\r\n// stand up a simple http server\r\nvar server = http.createServer(function(req, res) {\r\n  console.log('got request')\r\n  res.end('hello superagent!')\r\n})\r\n\r\n// Start listening\r\nserver.listen(1234, function() {\r\n\r\n  console.log('server listening')\r\n  \r\n  // Generate dummy data\r\n  var promise = new Promise(function(resolve, reject) {\r\n    \r\n    resolve({ hello: 'superagent' })\r\n    \r\n  }).then(function(data) {\r\n    \r\n    // generate a dummy request\r\n    return superagent.post('http://localhost:1234').send(data)\r\n    \r\n  }).then(function(res) {\r\n    // At this point, we should have a request\r\n   // that hasn't been fired yet, based on the docs.\r\n\r\n    // Pipe to the dest, fires the request and streams to the file\r\n    res.pipe(dest)\r\n    // kill the program\r\n    dest.once('close', function() {\r\n      console.log('wrote response')\r\n      process.exit()\r\n    })\r\n    \r\n  })\r\n  \r\n})\r\n```\r\n\r\nWith `superagent@<1.3.0`, the code works as expected and you will see a `wrote response` and the `response.txt` will have the correct text `hello superagent!`. \r\n\r\nThe problem with `superagent@^1.3.0` the request ( that should not have fired based on the docs ) is seen as a \"thenable\" and so the promise chain will call the `then()` method which fires off the request and returns the buffered response to the next promise chain call. Because of this, the pipe method will not work because the stream has already been exhausted, the program will never end, and the `response.txt` will have no content.\r\n "},"comment":{"url":"https://api.github.com/repos/visionmedia/superagent/issues/comments/171990943","html_url":"https://github.com/visionmedia/superagent/issues/852#issuecomment-171990943","issue_url":"https://api.github.com/repos/visionmedia/superagent/issues/852","id":171990943,"user":{"login":"focusaurus","id":482377,"avatar_url":"https://avatars.githubusercontent.com/u/482377?v=3","gravatar_id":"","url":"https://api.github.com/users/focusaurus","html_url":"https://github.com/focusaurus","followers_url":"https://api.github.com/users/focusaurus/followers","following_url":"https://api.github.com/users/focusaurus/following{/other_user}","gists_url":"https://api.github.com/users/focusaurus/gists{/gist_id}","starred_url":"https://api.github.com/users/focusaurus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/focusaurus/subscriptions","organizations_url":"https://api.github.com/users/focusaurus/orgs","repos_url":"https://api.github.com/users/focusaurus/repos","events_url":"https://api.github.com/users/focusaurus/events{/privacy}","received_events_url":"https://api.github.com/users/focusaurus/received_events","type":"User","site_admin":false},"created_at":"2016-01-15T15:26:31Z","updated_at":"2016-01-15T15:26:31Z","body":"Yeah this is unfortunate. If we do anything, I'd vote to remove the fake promise API entirely and bump semver major. I'd personally rather stick with a callback API that follows node core conventions and let folks do something like `Promise.promisifyAll(request.prototype)` (with bluebird) if they want Promises."}}