diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 8027c10..5f86d1f 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1 +1,2 @@ +- Fix: try return valid results when several status codes are returned by iotagents - Fix: return target error code instead of 500 error code (#167) diff --git a/lib/services/iotaRedirector.js b/lib/services/iotaRedirector.js index eda0151..ae0910d 100644 --- a/lib/services/iotaRedirector.js +++ b/lib/services/iotaRedirector.js @@ -29,9 +29,10 @@ const _ = require('underscore'); const async = require('async'); const domain = require('../utils/domain'); const fillService = domain.fillService; -var context = { +let context = { op: 'IoTAManager.Redirector' }; +const error40x = [400, 401, 403, 404]; function guessCollection(body) { if (body.services) { @@ -262,6 +263,9 @@ function createRequests(req, res, next) { for (let i = 0; i < req.protocolId.length; i++) { req.requests.push(createRequest(req, req.protocolId[i], req.body)); } + if (req.requests.length === 0) { + logger.warn(context, 'None request was created to be redirected due to not protocolId was found '); + } } next(); @@ -311,13 +315,18 @@ function processRequests(req, res, next) { ) ); } else if (body && body.length > 0) { - let parsedBody; + let parsedBody = []; let parseError; - + logger.debug(context, 'Response status: %s body: \n%s\n', response.statusCode, body); try { - parsedBody = JSON.parse(body); - if (response.statusCode === 409) { - parseError = new errors.DuplicateError(parsedBody); + if (error40x.includes(response.statusCode)) { + // avoid a parse body error hides response status code + parsedBody = []; + } else { + parsedBody = JSON.parse(body); + if (response.statusCode === 409) { + parseError = new errors.DuplicateError(parsedBody); + } } logger.debug(context, 'Response body from the redirected request parsed: \n\n%j\n', parsedBody); } catch (e) { @@ -356,7 +365,7 @@ function processRequests(req, res, next) { } for (let i = 0; i < results.length; i++) { - logger.debug(context, 'results[%s][1] %j ', i, results[i][1]); + logger.debug(context, 'Combining results[%s][1] %j ', i, results[i][1]); if (results[i][1].count) { totalCount += results[i][1].count; @@ -392,34 +401,76 @@ function processRequests(req, res, next) { let combinedResult; if (error) { - logger.error(context, 'The redirection ended up in error: ', error); + logger.error(context, 'The redirection ended up in error: %j', JSON.stringify(error)); next(error); } else { logger.debug(context, 'results %j', results); const statusCodes = _.uniq(results.map(extractStatusCode)); - if (statusCodes.length === 1) { if (req.method === 'POST' || req.method === 'DELETE' || req.method === 'PUT') { res.status(statusCodes[0]).send(); } else if (results.length >= 1) { combinedResult = combineResults(results); - + const logMsg = + 'statusCodes ' + + JSON.stringify(statusCodes) + + ' and combinedResults ' + + JSON.stringify(combinedResult) + + ', redirecting for ' + + req.method; if (combinedResult) { + logger.debug(context, logMsg); res.status(statusCodes[0]).json(combinedResult); } else { - next(new errors.TargetServerError('No valid replies from any IoTAgent', statusCodes[0])); + logger.warn(context, logMsg); + next( + new errors.TargetServerError( + 'No valid replies from any IoTAgent: ' + + JSON.stringify(results) + + ' redirecting request ' + + req.method, + statusCodes[0] + ) + ); } } else { + // req.method is GET and results.length = 0 res.status(statusCodes[0]).json({}); } + } else if (statusCodes.length > 1 && results.length >= 1 && req.method === 'GET') { + // check if there some valid statusCodes and then warn and return valid results + combinedResult = combineResults(results); + logger.warn( + context, + 'several statusCodes %j and combinedResults %j, redirecting for GET', + statusCodes, + combinedResult + ); + if (combinedResult) { + // Get valid result + res.status(statusCodes.sort()[0]).json(combinedResult); + } else { + next( + new errors.TargetServerError( + 'No valid replies from any IoTAgent: ' + + JSON.stringify(results) + + ' redirecting request ' + + req.method, + statusCodes.sort()[0] + ) + ); + } } else { + // statusCodes.length === 0 + // statusCodes.length > 1 && (req.method != GET || results.length < 1) const errorMsg = - 'Wrong status code obtained in some of the responses [' + + 'Wrong status code ' + JSON.stringify(statusCodes) + - '] redirecting request'; - + ' obtained in some of the responses [' + + JSON.stringify(results) + + '] redirecting request: ' + + req.method; logger.error(context, errorMsg); - next(new errors.TargetServerError(errorMsg)); } }