I've a situation where I found a solution, but I am not happy with it. I'm trying to find out a more elegant solution. Basically a library that:
As concept, the thing is simple: disable the encoding, recursively retry the request. However, the stream may not be consumed at once. It may be passed back to the client code, or it may be wrapped by methods that consume it in specific ways: saving it to a Buffer, or saving it to a file. Therefore it uses an "inner wrapper" aka the method that retrieves the stream and gives the OK for continuing the processing, and the "outer wrapper" that consumes the stream (saveBuffer() in the example code). I wrote some code that explains the thing that bothers me:
var Request = function (options) {
this.options = options;
};
Request.prototype.send = function (callback) {
this.stream = createStream(function () {
callback(null, success); // completion callback
});
this.stream.pause();
};
// save the stream as Buffer
Request.prototype.saveBuffer = function (callback) {
var self = this;
this.stream.on('error', function (err) {
// unfortunately this err does not appear in this.send
// as it is a stream decoding error that happens in
// edge cases after the stream is passed back successfully
if ("recoverable error") {
// this is the piece of code that bothers me
self.options.disableTroublesomeEncoding = true;
self = new Request(self.options);
self.send(function (err, res) {
if (err) {
callback(err);
return;
}
self.saveBuffer(callback);
});
return;
}
callback(err);
});
this.stream.on('success', function () {
callback(null, self.success());
});
this.stream.resume();
}
Request.prototype.success = function () {
return {
code: this.stream.code //, etc
}
};
// client code
var req = new Request(options);
req.send(function (err, res) {
// if no error, continue
req.saveBuffer(function (err, success) {
// handle error or success
// success is different than req.success()
// for recoverable errors
});
});
I create a new Request instance internally since the client code is already in saveBuffer() when the decoding error hits and that was the only easy way for reissuing send(). Basically, by assigning the new instance to self (where self = this) works properly internally. To get the proper success status by I have to pass it to the completion callback of the "outer callback". This is the thing that bothers me: req.success() has the wrong values as it doesn't reflect the state of the internally created Request object, but the values returned by the initial request that failed to decode.
Is it possible to have req.success() return the state of the internally created object instead of pointing to the original object?