YUKI Hiroshi
null+****@clear*****
Fri Aug 24 18:01:43 JST 2012
YUKI Hiroshi 2012-08-24 18:01:43 +0900 (Fri, 24 Aug 2012) New Revision: 293fbb6e59bfd06a757992b22276181fe3cc31f4 https://github.com/groonga/gcs/commit/293fbb6e59bfd06a757992b22276181fe3cc31f4 Log: Return ACS compatible error response from search API around unknown field Modified files: lib/api/2011-02-01/search.js lib/bq-translator.js test/bq-translator.test.js Modified: lib/api/2011-02-01/search.js (+18 -11) =================================================================== --- lib/api/2011-02-01/search.js 2012-08-24 17:02:17 +0900 (f843850) +++ lib/api/2011-02-01/search.js 2012-08-24 18:01:43 +0900 (96ff15a) @@ -80,18 +80,22 @@ function select(context, options, callback) { } function createErrorBody(options) { + var messages = []; + if (options.messages) { + messages = options.messages; + } else { + messages.push({ + severity: 'fatal', + code: '', + message: options.message || '' + }); + } return { error: 'info', rid: options.rid, 'time-ms': options.elapsedTime || 0, 'cpu-time-ms': 0, // TODO - messages: [ - { - severity: 'fatal', - code: '', - message: options.message || '' - } - ] + messages: messages }; } @@ -147,10 +151,13 @@ exports.createHandler = function(context) { try { filters.push(translator.translate()); } catch (error) { - var body = createErrorBody({ - rid: dummyRid, - message: 'Invalid bq value: ' + (error.message || error) - }); + var errorData = { rid: dummyRid }; + if (error.message == 'validation error') { + errorData.messages = [error.data]; + } else { + errorData.message = 'Invalid bq value: ' + (error.message || error); + } + var body = createErrorBody(errorData); return response.send(body, 400); } if (matchExpr.length > 0) { Modified: lib/bq-translator.js (+18 -4) =================================================================== --- lib/bq-translator.js 2012-08-24 17:02:17 +0900 (1b25a19) +++ lib/bq-translator.js 2012-08-24 18:01:43 +0900 (8245d16) @@ -50,6 +50,15 @@ BooleanQueryTranslator.prototype = { message += ": " + detail; throw new Error(message); }, + throwValidationError: function(code, message) { + var error = new Error('validation error'); + error.data = { + code: code, + severity: 'fatal', + message: message + }; + throw error; + }, skipSpaces: function() { for (; this.offset < this.query.length; this.offset++) { if (this.query[this.offset] != " ") { @@ -403,13 +412,18 @@ BooleanQueryTranslator.prototype = { } }, // Get an instance of "IndexField". - // Unknown field works as "text, searchable" field. + // Unknown field works as "text, searchable" field, if it works without domain. getField: function(fieldName) { var field; - if (this.domain) { + if (this.domain && fieldName) { field = this.domain.getIndexField(fieldName); - if (field && !field.exists()) - field.type = "text"; + if (!field.exists()) + this.throwValidationError( + 'CS-UnknownFieldInMatchExpression', + 'Field \'' + fieldName + '\' is not defined in the metadata for this ' + + 'collection. All fields used in the match expression must be ' + + 'defined in the metadata.' + ); } if (!field) field = new IndexField(fieldName).setType("text"); Modified: test/bq-translator.test.js (+11 -0) =================================================================== --- test/bq-translator.test.js 2012-08-24 17:02:17 +0900 (64b5199) +++ test/bq-translator.test.js 2012-08-24 18:01:43 +0900 (14883ba) @@ -157,6 +157,17 @@ suite('BoolanQueryTranslator', function() { temporaryDatabase = utils.createTemporaryDatabase(); context = temporaryDatabase.get(); domain = new Domain('test', context).createSync(); + [ + 'type', + 'name', + 'field', + 'field1', + 'field2', + 'field3' + ].forEach(function(field) { + domain.getIndexField(field).setType('text') + .setFacetEnabled(true).setSearchEnabled(true).createSync(); + }); domain.getIndexField('literalfield').setType('literal') .setFacetEnabled(true).setSearchEnabled(true).createSync(); }); -------------- next part -------------- HTML����������������������������...Download