Skip to content

Commit 2fae800

Browse files
committed
Merge pull request #76 from rakyll/callback-stream
storage: Streaming operations should return response body as an object
2 parents 33e6373 + a1f94b8 commit 2fae800

File tree

5 files changed

+75
-31
lines changed

5 files changed

+75
-31
lines changed

lib/common/util.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,38 @@ module.exports.format = function(templ, args) {
4949
return templ;
5050
};
5151

52-
module.exports.noop = function(){};
52+
var noop = function() {};
5353

54-
module.exports.ApiError = function (errorBody) {
54+
module.exports.noop = noop;
55+
56+
function ApiError (errorBody) {
5557
Error.call(this);
5658
Error.captureStackTrace(this, arguments.callee);
5759
this.errors = errorBody.errors;
5860
this.code = errorBody.code;
5961
this.message = errorBody.message;
60-
}
62+
};
6163

62-
util.inherits(module.exports.ApiError, Error);
64+
util.inherits(ApiError, Error);
65+
66+
module.exports.handleResp = function(err, resp, body, opt_callback) {
67+
var callback = opt_callback || noop;
68+
if (err) {
69+
callback(err);
70+
return;
71+
}
72+
if (typeof body === 'string') {
73+
try {
74+
body = JSON.parse(body);
75+
} catch(err) {}
76+
}
77+
if (body && body.error) {
78+
callback(new ApiError(body.error));
79+
return;
80+
}
81+
if (resp && (resp.statusCode < 200 || resp.statusCode > 299)) {
82+
callback(new Error('error during request, statusCode: ' + resp.statusCode));
83+
return;
84+
}
85+
callback(null, body, resp);
86+
};

lib/datastore/index.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,7 @@ Transaction.prototype.makeReq = function(method, req, callback) {
301301
uri: DATASTORE_BASE_URL + '/' + this.datasetId + '/' + method,
302302
json: req
303303
}, function(err, res, body) {
304-
if (body && body.error) {
305-
var error = new util.ApiError(body.error);
306-
return callback(error, null);
307-
}
308-
callback(err, body);
304+
util.handleResp(err, res, body, callback);
309305
});
310306
};
311307

lib/pubsub/index.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ Connection.prototype.fullProjectName_ = function() {
398398
});
399399
};
400400

401-
// TOOD(jbd): Don't duplicate, unify this with bucket.makeReq.
402401
Connection.prototype.makeReq = function(method, path, q, body, callback) {
403402
var reqOpts = {
404403
method: method,
@@ -412,13 +411,7 @@ Connection.prototype.makeReq = function(method, path, q, body, callback) {
412411
reqOpts.json = body;
413412
}
414413
this.conn.req(reqOpts, function(err, res, body) {
415-
if (body && body.error) {
416-
callback(new util.ApiError(body.error)); return;
417-
}
418-
if (res && (res.statusCode < 200 || res.statusCode > 299)) {
419-
callback(new Error('error during request, statusCode: ' + res.statusCode)); return;
420-
}
421-
callback(null, body);
414+
util.handleResp(err, res, body, callback);
422415
});
423416
};
424417

lib/storage/index.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,12 @@ var STORAGE_BASE_URL = 'https://www.googleapis.com/storage/v1/b';
3333
STORAGE_UPLOAD_BASE_URL = 'https://www.googleapis.com/upload/storage/v1/b';
3434

3535
var reqStreamToCallback = function(st, callback) {
36+
st.callback = util.noop;
3637
st.on('error', function(err) {
3738
callback(err);
3839
});
3940
st.on('complete', function(resp) {
40-
// TODO(jbd): Buffer the response to pass the resp body
41-
// to the callback.
42-
if (resp.statusCode < 200 || resp.statusCode > 299) {
43-
return callback(new Error('error during request, statusCode: ' + resp.statusCode), resp);
44-
}
45-
callback(null, resp);
41+
util.handleResp(null, resp, resp.body, callback);
4642
});
4743
};
4844

@@ -330,13 +326,7 @@ Bucket.prototype.makeReq = function(method, path, q, body, callback) {
330326
reqOpts.json = body;
331327
}
332328
this.conn.req(reqOpts, function(err, res, body) {
333-
if (body && body.error) {
334-
return callback(body.error);
335-
}
336-
if (res && (res.statusCode < 200 || res.statusCode > 299)) {
337-
return callback(new Error('error during request, statusCode: ' + res.statusCode));
338-
}
339-
callback(err, body);
329+
util.handleResp(err, res, body, callback);
340330
});
341331
};
342332

test/common.util.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,45 @@ describe('arrayize', function() {
3232
assert.deepEqual(o, ['text']);
3333
done();
3434
});
35-
});
35+
});
36+
37+
describe('handleResp', function() {
38+
39+
it('should handle errors', function(done) {
40+
var defaultErr = new Error('new error');
41+
util.handleResp(defaultErr, null, null, function(err) {
42+
assert.equal(err, defaultErr);
43+
done();
44+
});
45+
});
46+
47+
it('should handle body errors', function(done) {
48+
var apiErr = {
49+
errors: [{ foo: 'bar' }],
50+
code: 400,
51+
message: 'an error occurred'
52+
}
53+
util.handleResp(null, {}, { error: apiErr }, function(err) {
54+
assert.deepEqual(err.errors, apiErr.errors);
55+
assert.strictEqual(err.code, apiErr.code);
56+
assert.deepEqual(err.message, apiErr.message);
57+
done();
58+
});
59+
});
60+
61+
it('should try to parse JSON if body is string', function(done) {
62+
var body = '{ "foo": "bar" }';
63+
util.handleResp(null, {}, body, function(err, body) {
64+
assert.strictEqual(body.foo, 'bar');
65+
done();
66+
});
67+
});
68+
69+
it('should return status code as an error if there are not other errors', function(done) {
70+
util.handleResp(null, { statusCode: 400 }, null, function(err) {
71+
assert.strictEqual(err.message, 'error during request, statusCode: 400');
72+
done();
73+
});
74+
});
75+
76+
});

0 commit comments

Comments
 (0)