/**
* @version 1.0
* @author Boris GBAHOUE
* @file Response wrapper to structure the messages between our front and back
* @module amiwo/rest
* @class ResponseJSON
*/
// =======================================================================
// BASE SETUP
// =======================================================================
var GenericError = require('./error/GenericError');
// =======================================================================
// METHODS
// =======================================================================
/**
* Wrapper to build the ResponseJSON for non error replies
* Every response generated as a result of a REST call is a JSON object.
*
* @returns
* - JSON object
* - If ok:
* - connection: ok, ko
* - http_code (as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
* . 200 (ok): the request has succeeded
* . 201 (created): the request has been fulfilled and resulted in a new resource being created
* . 204 (no content): the server has fulfilled the request but does not need to return an entity-body
* - data: object
* - If failed:
* - message: a message explaining the problem in plain English
* - resource: the REST API called
* - method: the HTTP method used
*
* @public
* @memberOf ResponseJSON
*/
exports.responseJSON = function(http_code, obj) {
var response = {};
response.connection = "ok";
response.http_code = http_code;
response.data = obj;
return response;
};
/**
* Wrapper to build a ResponseJSON when an error occured
* Every response generated as a result of a REST call is a JSON object.
* In case of error, the data returned are more detailed and are useful
* to understand why the request was rejected.
*
* @returns
* - JSON object
* - connection: ko
* - http_code: error code (set to 'http_code' param when not null or 500 otherwise)
* - message: a message explaining the problem in plain English
* - resource: the REST API called
* - method: the HTTP method used
* - data: other data to describe the issue
*
* @public
* @memberOf ResponseJSON
*/
exports.errorJSON = function(message, resource, method, obj, http_code) {
var response = {};
response.connection = "ko";
response.message = message;
response.resource = resource;
response.method = method;
if (obj != null)
response.data = obj;
if (http_code == null) {
response.http_code = 500;
} else {
var code = Number(http_code);
response.http_code = isNaN(code) ? 500 : code;
}
return response;
}
/**
* Test if an Object is a proper ResponseJSON
*
* @param {Object}
* @return {Boolean}
*
* @public
* @memberOf ResponseJSON
*/
exports.isValid = function(json) {
if (json == null) return false;
if (json.connection == "ok") {
return (!isNaN(json.http_code) && json.hasOwnProperty("data"));
} else if (json.connection == "ko") {
return (json.hasOwnProperty("message") && json.hasOwnProperty("resource") && json.hasOwnProperty("method") && !isNaN(json.http_code));
} else {
return false;
}
}
/**
* Process an error and returns a properly formatted JSON
*
* @param {Object} msg
* @param {Express.Request} req
*
* @return {ErrorJSON}
*
* @public
* @memberOf ResponseJSON
*/
exports.processError = function(msg, req) {
let tmp;
let http_code = 500;
if (msg instanceof GenericError) {
tmp = msg.object;
if (!this.isValid(tmp)) { // Check if tmp is a properly formatted errorJSON
if (tmp && tmp.http_code) http_code = tmp.http_code;
tmp = this.errorJSON(msg.message || "Unexpected Error", req.url, req.method, tmp, http_code);
}
} else if (msg instanceof Error) {
let $err = msg; // for clarity
let $message = $err.message ? $err.constructor.name+": "+$err.message : "Unexpected error "+$err.constructor.name;
tmp = this.errorJSON($message, req.url, req.method, $err.object, http_code);
} else if (typeof msg == 'string') {
tmp = this.errorJSON(msg, req.url, req.method.toUpperCase(), null, http_code);
} else {
tmp = this.errorJSON("Unexpected error : '"+((msg instanceof Object) ? JSON.stringify(msg) : msg)+"'", req.url, req.method.toUpperCase(), msg, http_code);
}
return tmp;
}