Skip to content

Commit

Permalink
Merge pull request #86 from IGME-Research-Studio/IS-40-json-res
Browse files Browse the repository at this point in the history
Update responses to be JSON only
  • Loading branch information
dropofwill committed Oct 28, 2015
2 parents 8295e43 + ccc07a7 commit 7d82f9d
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 309 deletions.
88 changes: 31 additions & 57 deletions api/responses/badRequest.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,39 @@
/**
* 400 (Bad Request) Handler
*
* Usage:
* return res.badRequest();
* return res.badRequest(data);
* return res.badRequest(data, 'some/specific/badRequest/view');
*
* e.g.:
* ```
* return res.badRequest(
* 'Please choose a valid `password` (6-12 characters)',
* 'trial/signup'
* );
* ```
*/
* 400 (Bad Request) Handler
*
* @description
* The request cannot be fulfilled due to bad syntax.
* General error when fulfilling the request would cause an invalid state.
* Domain validation errors, missing data, etc.
*
* @param {Object} [data] arbitrary data object
* @param {Object} [options]
* @param {String} [options.code]
* @param {String} [options.message]
*
* @see {@link ErrorCodeService}
* {@link https://github.com/IncoCode/sails-service-error-codes#default-error-codes Default error code definitions}
*
* @example
* return res.badRequest();
* return res.badRequest(data);
* return res.badRequest(data, {message: 'Bad syntax, yo!'});
*/

const ErrorCodes = require('sails-service-error-codes').getCodes();
const _ = require('lodash');

module.exports = function badRequest(data, options) {

// Get access to `req`, `res`, & `sails`
const req = this.req;
const res = this.res;
const sails = req._sails;
const defaults = {
code: ErrorCodes.badRequest.code,
message: ErrorCodes.badRequest.message,
data: ((sails.config.environment === 'production') ? undefined : data || {}),
};

// Set status code
res.status(400);
const response = _.defaults(options || {}, defaults);

// Log error to console
if (data !== undefined) {
sails.log.verbose('Sending 400 ("Bad Request") response: \n', data);
}
else sails.log.verbose('Sending 400 ("Bad Request") response');

// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production') {
data = undefined;
}

// If the user-agent wants JSON, always respond with JSON
if (req.wantsJSON) {
return res.jsonx(data);
}

// If second argument is a string, we take that to mean it refers to a view.
// If it was omitted, use an empty object (`{}`)
options = (typeof options === 'string') ? { view: options } : options || {};

// If a view was provided in options, serve it.
// Otherwise try to guess an appropriate view, or if that doesn't
// work, just send JSON.
if (options.view) {
return res.view(options.view, { data: data });
}

// If no second argument provided, try to serve the implied view,
// but fall back to sending JSON(P) if no view can be inferred.
else {
return res.guessView({ data: data }, function couldNotGuessView() {
return res.jsonx(data);
});
}
this.res.status(400);
this.res.jsonx(response);
};

42 changes: 42 additions & 0 deletions api/responses/created.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* 403 (Created) Handler
*
* @description
* The request has been fulfilled and resulted in a new resource being created.
* Successful creation occurred (via either POST or PUT).
* Set the Location header to contain a link to the newly-created resource
* (on POST).
* Response body content may or may not be present.
*
* @param {Object} [data] arbitrary data object
* @param {Object} [options]
* @param {String} [options.code]
* @param {String} [options.message]
* @param {Object} [options.root]
*
* @see {@link ErrorCodeService}
* {@link https://github.com/IncoCode/sails-service-error-codes#default-error-codes Default error code definitions}
*
* @example
* return res.created();
* return res.created(data);
* return res.created(data, {message: 'I made it'});
*/

const ErrorCodes = require('sails-service-error-codes').getCodes();
const _ = require('lodash');

module.exports = function created(data, options) {

const defaults = {
code: ErrorCodes.created.code,
message: ErrorCodes.created.message,
data: ((sails.config.environment === 'production') ? undefined : data || {}),
};

const response = _.defaults(options || {}, defaults);

this.res.status(201);
this.res.jsonx(response);
};

101 changes: 33 additions & 68 deletions api/responses/forbidden.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,41 @@
/**
* 403 (Forbidden) Handler
*
* Usage:
* return res.forbidden();
* return res.forbidden(err);
* return res.forbidden(err, 'some/specific/forbidden/view');
*
* e.g.:
* ```
* return res.forbidden('Access denied.');
* ```
*/
* 403 (Forbidden) Handler
*
* @description
* The request was a legal request, but the server is refusing to respond to it.
* Unlike a 401 Unauthorized response, authenticating will make no difference.
* Error code for user not authorized to perform the operation or the resource
* is unavailable for some reason.
*
* @param {Object} [data] arbitrary data object
* @param {Object} [options]
* @param {String} [options.code]
* @param {String} [options.message]
* @param {Object} [options.root]
*
* @see {@link ErrorCodeService}
* {@link https://github.com/IncoCode/sails-service-error-codes#default-error-codes Default error code definitions}
*
* @example
* return res.forbidden();
* return res.forbidden(data);
* return res.forbidden(data, {message: 'I'm sorry Dave, I'm afraid I can't do that'});
*/

const ErrorCodes = require('sails-service-error-codes').getCodes();
const _ = require('lodash');

module.exports = function forbidden(data, options) {

// Get access to `req`, `res`, & `sails`
const req = this.req;
const res = this.res;
const sails = req._sails;
const defaults = {
code: ErrorCodes.forbidden.code,
message: ErrorCodes.forbidden.message,
data: ((sails.config.environment === 'production') ? undefined : data || {}),
};

// Set status code
res.status(403);
const response = _.defaults(options || {}, defaults);

// Log error to console
if (data !== undefined) {
sails.log.verbose('Sending 403 ("Forbidden") response: \n', data);
}
else sails.log.verbose('Sending 403 ("Forbidden") response');

// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production') {
data = undefined;
}

// If the user-agent wants JSON, always respond with JSON
if (req.wantsJSON) {
return res.jsonx(data);
}

// If second argument is a string, we take that to mean it refers to a view.
// If it was omitted, use an empty object (`{}`)
options = (typeof options === 'string') ? { view: options } : options || {};

// If a view was provided in options, serve it.
// Otherwise try to guess an appropriate view, or if that doesn't
// work, just send JSON.
if (options.view) {
return res.view(options.view, { data: data });
}

// If no second argument provided, try to serve the default view,
// but fall back to sending JSON(P) if any errors occur.
else {
return res.view('403', { data: data }, (err, html) => {
// If a view error occured, fall back to JSON(P).
if (err) {
// Additionally:
// • If the view was missing, ignore the error but provide a verbose log.
if (err.code === 'E_VIEW_FAILED') {
sails.log.verbose('res.forbidden() :: Could not locate view for error page (sending JSON instead). Details: ', err);
}
// Otherwise, if this was a more serious error, log to the console with the details.
else {
sails.log.warn('res.forbidden() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err);
}
return res.jsonx(data);
}

return res.send(html);
});
}
this.res.status(403);
this.res.jsonx(response);
};

111 changes: 37 additions & 74 deletions api/responses/notFound.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,45 @@
/**
* 404 (Not Found) Handler
*
* Usage:
* return res.notFound();
* return res.notFound(err);
* return res.notFound(err, 'some/specific/notfound/view');
*
* e.g.:
* ```
* return res.notFound();
* ```
*
* NOTE:
* If a request doesn't match any explicit routes (i.e. `config/routes.js`)
* or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()`
* automatically.
*/
* 404 (Not Found) Handler
*
* @description
* The requested resource could not be found but may be available again in the
* future. Subsequent requests by the client are permissible.
* Used when the requested resource is not found, whether it doesn't exist.
*
* @param {Object} [data] arbitrary data object
* @param {Object} [options]
* @param {String} [options.code]
* @param {String} [options.message]
* @param {Object} [options.root]
*
* @see {@link ErrorCodeService}
* {@link https://github.com/IncoCode/sails-service-error-codes#default-error-codes Default error code definitions}
*
* @example
* return res.notFound();
* return res.notFound(data);
* return res.notFound(data, {message: 'That's not here'});
*
* NOTE:
* If a request doesn't match any explicit routes (i.e. `config/routes.js`)
* or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()`
* automatically.
*/

const ErrorCodes = require('sails-service-error-codes').getCodes();
const _ = require('lodash');

module.exports = function notFound(data, options) {

// Get access to `req`, `res`, & `sails`
const req = this.req;
const res = this.res;
const sails = req._sails;
const defaults = {
code: ErrorCodes.notFound.code,
message: ErrorCodes.notFound.message,
data: ((sails.config.environment === 'production') ? undefined : data || {}),
};

// Set status code
res.status(404);
const response = _.defaults(options || {}, defaults);

// Log error to console
if (data !== undefined) {
sails.log.verbose('Sending 404 ("Not Found") response: \n', data);
}
else sails.log.verbose('Sending 404 ("Not Found") response');

// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production') {
data = undefined;
}

// If the user-agent wants JSON, always respond with JSON
if (req.wantsJSON) {
return res.jsonx(data);
}

// If second argument is a string, we take that to mean it refers to a view.
// If it was omitted, use an empty object (`{}`)
options = (typeof options === 'string') ? { view: options } : options || {};

// If a view was provided in options, serve it.
// Otherwise try to guess an appropriate view, or if that doesn't
// work, just send JSON.
if (options.view) {
return res.view(options.view, { data: data });
}

// If no second argument provided, try to serve the default view,
// but fall back to sending JSON(P) if any errors occur.
else {
return res.view('404', { data: data }, (err, html) => {
// If a view error occured, fall back to JSON(P).
if (err) {
//
// Additionally:
// • If the view was missing, ignore the error but provide a verbose log.
if (err.code === 'E_VIEW_FAILED') {
sails.log.verbose('res.notFound() :: Could not locate view for error page (sending JSON instead). Details: ', err);
}
// Otherwise, if this was a more serious error, log to the console with the details.
else {
sails.log.warn('res.notFound() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err);
}
return res.jsonx(data);
}

return res.send(html);
});
}
this.res.status(404);
this.res.jsonx(response);
};

Loading

0 comments on commit 7d82f9d

Please sign in to comment.