mirror of https://github.com/pelias/api.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.6 KiB
74 lines
2.6 KiB
var check = require('check-types'), |
|
es = require('elasticsearch'), |
|
logger = require( 'pelias-logger' ).get( 'api' ), |
|
exceptions = require('elasticsearch-exceptions/lib/exceptions/SupportedExceptions'); |
|
|
|
// create a list of regular expressions to match against. |
|
// note: list created when the server starts up; for performance reasons. |
|
var exceptionRegexList = exceptions.map( function( exceptionName ){ |
|
return new RegExp( '^' + exceptionName ); |
|
}); |
|
|
|
function sendJSONResponse(req, res, next) { |
|
|
|
// do nothing if no result data set |
|
if (!res || !check.object(res.body) || !check.object(res.body.geocoding)) { |
|
return next(); |
|
} |
|
|
|
// default status |
|
var statusCode = 200; // 200 OK |
|
|
|
// vary status code whenever an error was reported |
|
var geocoding = res.body.geocoding; |
|
|
|
if( check.array( geocoding.errors ) && geocoding.errors.length ){ |
|
|
|
// default status for errors is 400 Bad Request |
|
statusCode = 400; // 400 Bad Request |
|
|
|
// iterate over all reported errors |
|
geocoding.errors.forEach( function( err ){ |
|
|
|
// custom status codes for instances of the Error() object. |
|
if( err instanceof Error ){ |
|
/* |
|
elasticsearch errors |
|
see: https://github.com/elastic/elasticsearch-js/blob/master/src/lib/errors.js |
|
|
|
408 Request Timeout |
|
500 Internal Server Error |
|
502 Bad Gateway |
|
*/ |
|
if( err instanceof es.errors.RequestTimeout ){ statusCode = Math.max( statusCode, 408 ); } |
|
else if( err instanceof es.errors.NoConnections ){ statusCode = Math.max( statusCode, 502 ); } |
|
else if( err instanceof es.errors.ConnectionFault ){ statusCode = Math.max( statusCode, 502 ); } |
|
else { |
|
logger.warn( 'unknown geocoding error object:', err.constructor.name, err ); |
|
statusCode = Math.max( statusCode, 500 ); |
|
} |
|
|
|
/* |
|
some elasticsearch errors are only returned as strings (not instances of Error). |
|
in this case we (unfortunately) need to match the exception at position 0 inside the string. |
|
*/ |
|
} else if( check.string( err ) ){ |
|
for( var i=0; i<exceptionRegexList.length; i++ ){ |
|
// check error string against a list of known elasticsearch exceptions |
|
if( err.match( exceptionRegexList[i] ) ){ |
|
statusCode = Math.max( statusCode, 500 ); |
|
break; // break on first match |
|
} |
|
logger.warn( 'unknown geocoding error string:', err ); |
|
} |
|
} else { |
|
logger.warn( 'unknown geocoding error type:', typeof err, err ); |
|
} |
|
}); |
|
} |
|
|
|
// respond |
|
return res.status(statusCode).json(res.body); |
|
} |
|
|
|
module.exports = sendJSONResponse;
|
|
|