Skip to content

Commit

Permalink
Closes #1395, closes #1404
Browse files Browse the repository at this point in the history
  • Loading branch information
Eran Hammer committed Feb 7, 2014
1 parent fbf0fda commit 0c3cf12
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 12 deletions.
3 changes: 2 additions & 1 deletion docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ When creating a server instance, the following options configure the server's be
- `maxSockets` - sets the number of sockets available per outgoing host connection. `null` means use node.js default value.
Impacts all outgoing client connections using the defualt HTTP/HTTPS agent. Defaults to `Infinity`.

- `validation` - options to pass to [Joi](http://github.com/spumko/joi). Useful to set global options such as `stripUnknown` or `abortEarly` (the complete list is available [here](https://github.com/spumko/joi#validatevalue-schema-options)). Defaults to `undefined`.
- `validation` - options to pass to [Joi](http://github.com/spumko/joi). Useful to set global options such as `stripUnknown` or `abortEarly` (the complete list is available [here](https://github.com/spumko/joi#validatevalue-schema-options)). Defaults to `{ modify: true }` which will cast data to the specified
types.

- <a name="server.config.views"></a>`views` - enables support for view rendering (using templates to generate responses). Disabled by default.
To enable, set to an object with the following options:
Expand Down
3 changes: 1 addition & 2 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,7 @@ internals.Request.prototype.log = function (tags, data, timestamp) {
this.server.settings.debug.request &&
Utils.intersect(tagsMap, this.server.settings.debug.request, true)) {

console.error('Debug:', item.tags.join(', '), data ? '\n ' +
(data.stack || (typeof data === 'object' ? JSON.stringify(data) : data)) : '');
console.error('Debug:', item.tags.join(', '), (data ? '\n ' + (data.stack || (typeof data === 'object' ? Utils.stringify(data) : data)) : ''));
}
};

Expand Down
8 changes: 1 addition & 7 deletions lib/response/payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,14 @@ var Utils = require('../utils');
var internals = {};


exports = module.exports = internals.Payload = function (payload, request, options) {
exports = module.exports = internals.Payload = function (payload, options) {

Stream.Readable.call(this);
this._data = (payload === undefined ? null : payload);
this._prefix = null;
this._suffix = null;
this._sizeOffset = 0;
this._encoding = options.encoding;

if (options && options.stringify) {
var space = options.stringify.space || request.server.settings.json.space;
var replacer = options.stringify.replacer || request.server.settings.json.replacer;
this._data = JSON.stringify(payload, replacer, space);
}
};

Utils.inherits(internals.Payload, Stream.Readable);
Expand Down
19 changes: 18 additions & 1 deletion lib/response/plain.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,24 @@ internals.Plain.prototype.takeover = function () {

internals.Plain.prototype._marshall = function (request, callback) {

this._payload = (this.source instanceof Stream ? this.source : new Payload(this.source, request, this.settings));
if (this.source instanceof Stream) {
this._payload = this.source;
return callback();
}

var payload = this.source;
if (this.settings.stringify) {
var space = this.settings.stringify.space || request.server.settings.json.space;
var replacer = this.settings.stringify.replacer || request.server.settings.json.replacer;
try {
payload = JSON.stringify(payload, replacer, space);
}
catch (err) {
return callback(err);
}
}

this._payload = new Payload(payload, this.settings);
return callback();
};

Expand Down
9 changes: 9 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,12 @@ exports.version = function () {
};


exports.stringify = function () {

try {
return JSON.stringify.apply(null, arguments);
}
catch (err) {
return '[Cannot display object: ' + err.message + ']';
}
};
2 changes: 1 addition & 1 deletion lib/views.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ internals.Response.prototype._marshall = function (request, next) {
return next(err);
}

self._payload = new Response.Payload(rendered, request, self.settings);
self._payload = new Response.Payload(rendered, self.settings);
if (config.contentType) {
self.type(config.contentType);
}
Expand Down
57 changes: 57 additions & 0 deletions test/integration/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,63 @@ describe('Request', function () {
});
});

it('outputs log data to debug console', function (done) {

var handler = function (request, reply) {

request.log(['implementation'], 'data');
reply();
};

var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', handler: handler });

var orig = console.error;
console.error = function () {

expect(arguments[0]).to.equal('Debug:');
expect(arguments[1]).to.equal('implementation');
expect(arguments[2]).to.equal('\n data');
console.error = orig;
done();
};

server.inject('/', function (res) {

expect(res.statusCode).to.equal(200);
});
});

it('handles invalid log data object stringify', function (done) {

var handler = function (request, reply) {

var obj = {};
obj.a = obj;

request.log(['implementation'], obj);
reply();
};

var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', handler: handler });

var orig = console.error;
console.error = function () {

expect(arguments[0]).to.equal('Debug:');
expect(arguments[1]).to.equal('implementation');
expect(arguments[2]).to.equal('\n [Cannot display object: Converting circular structure to JSON]');
console.error = orig;
done();
};

server.inject('/', function (res) {

expect(res.statusCode).to.equal(200);
});
});

it('ignores second call to onReply()', function (done) {

var server = new Hapi.Server();
Expand Down
19 changes: 19 additions & 0 deletions test/integration/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,25 @@ describe('Response', function () {
done();
});
});

it('captures object which cannot be stringify', function (done) {

var handler = function (request, reply) {

var obj = {};
obj.a = obj;
reply(obj);
};

var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', handler: handler });

server.inject('/', function (res) {

expect(res.statusCode).to.equal(500);
done();
});
});
});

describe('Error', function () {
Expand Down

0 comments on commit 0c3cf12

Please sign in to comment.