{"action":"created","issue":{"url":"https://api.github.com/repos/vowsjs/vows/issues/307","labels_url":"https://api.github.com/repos/vowsjs/vows/issues/307/labels{/name}","comments_url":"https://api.github.com/repos/vowsjs/vows/issues/307/comments","events_url":"https://api.github.com/repos/vowsjs/vows/issues/307/events","html_url":"https://github.com/vowsjs/vows/pull/307","id":36975155,"number":307,"title":"Add `this.callback` alternative w/o error argument","user":{"login":"moteutsch","id":4185570,"avatar_url":"https://avatars.githubusercontent.com/u/4185570?v=3","gravatar_id":"","url":"https://api.github.com/users/moteutsch","html_url":"https://github.com/moteutsch","followers_url":"https://api.github.com/users/moteutsch/followers","following_url":"https://api.github.com/users/moteutsch/following{/other_user}","gists_url":"https://api.github.com/users/moteutsch/gists{/gist_id}","starred_url":"https://api.github.com/users/moteutsch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/moteutsch/subscriptions","organizations_url":"https://api.github.com/users/moteutsch/orgs","repos_url":"https://api.github.com/users/moteutsch/repos","events_url":"https://api.github.com/users/moteutsch/events{/privacy}","received_events_url":"https://api.github.com/users/moteutsch/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/vowsjs/vows/labels/error-handling","name":"error-handling","color":"e11d21"},{"url":"https://api.github.com/repos/vowsjs/vows/labels/v1.0.0","name":"v1.0.0","color":"bfe5bf"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2014-07-02T11:59:56Z","updated_at":"2015-01-28T17:25:28Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/vowsjs/vows/pulls/307","html_url":"https://github.com/vowsjs/vows/pull/307","diff_url":"https://github.com/vowsjs/vows/pull/307.diff","patch_url":"https://github.com/vowsjs/vows/pull/307.patch"},"body":"Added a function `this.callbackWithoutError` in addition to `this.callback`. This will be used on a case-by-case basis when `topic` is asynchronous and result callback doesn't pass error as first parameter, instead passing the result (to be passed to a vow)."},"comment":{"url":"https://api.github.com/repos/vowsjs/vows/issues/comments/71876666","html_url":"https://github.com/vowsjs/vows/pull/307#issuecomment-71876666","issue_url":"https://api.github.com/repos/vowsjs/vows/issues/307","id":71876666,"user":{"login":"silkentrance","id":6068824,"avatar_url":"https://avatars.githubusercontent.com/u/6068824?v=3","gravatar_id":"","url":"https://api.github.com/users/silkentrance","html_url":"https://github.com/silkentrance","followers_url":"https://api.github.com/users/silkentrance/followers","following_url":"https://api.github.com/users/silkentrance/following{/other_user}","gists_url":"https://api.github.com/users/silkentrance/gists{/gist_id}","starred_url":"https://api.github.com/users/silkentrance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/silkentrance/subscriptions","organizations_url":"https://api.github.com/users/silkentrance/orgs","repos_url":"https://api.github.com/users/silkentrance/repos","events_url":"https://api.github.com/users/silkentrance/events{/privacy}","received_events_url":"https://api.github.com/users/silkentrance/received_events","type":"User","site_admin":false},"created_at":"2015-01-28T17:25:28Z","updated_at":"2015-01-28T17:25:28Z","body":"@indexzero\r\n\r\nActually, I am having a hard time understanding the issue in the first place. Not so much the asynchronous part, just the special casing that this would introduce into the otherwise clean api.\r\n\r\nAnd, considering the provided examples over at vowsjs.org dealing with asynchronous testing,\r\nis missing the point. Why introduce an additional method if you can always also pass null as the first parameter? See here\r\n\r\n```\r\nexports.Banana.prototype = {\r\n    peel: function (callback) {\r\n        process.nextTick(function () {\r\n            callback(null, new(exports.PeeledBanana));\r\n        });\r\n    },\r\n    peelSync: function () { return new(exports.PeeledBanana) }\r\n};\r\n\r\nand later on\r\n\r\n        'when peeled *asynchronously*': {\r\n            topic: function (banana) {\r\n                banana.peel(this.callback);\r\n            },\r\n            'results in a `PeeledBanana`': function (err, result) {\r\n                assert.instanceOf (result, PeeledBanana);\r\n            }\r\n        }\r\n```\r\n\r\nI believe that a minority of APIs will actually work this way, not passing the error as first parameter to the callback, something which has been established long ago in the node apis. If the OP wants to support their own apis which do digress from the established pattern, then they should be using a wrapper, e.g.\r\n\r\n```\r\n            topic: function (banana) {\r\n                var self = this;\r\n                banana.peel(function (result) {self.callback(null, result);});\r\n            },\r\n```\r\n\r\nI'd say, ignore and close as this is more about special casing APIs that do not conform to the best practices that have already been established."}}