From ddb5efeb259bfc965641b3f7b249d456b28cb876 Mon Sep 17 00:00:00 2001 From: uboness Date: Fri, 8 May 2015 03:18:16 +0200 Subject: [PATCH] Throw appropriate error when input is empty When the watch `input` is an empty object, we need to throw an appropriate error indicating the problem (instead of the NPE that is currently thrown) Closes elastic/elasticsearch#427 Original commit: elastic/x-pack-elasticsearch@c8b27e6653600da9d6ef986e3bf3959069f21507 --- .../watcher/input/InputRegistry.java | 15 ++++++- .../watcher/input/InputRegistryTests.java | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/elasticsearch/watcher/input/InputRegistryTests.java diff --git a/src/main/java/org/elasticsearch/watcher/input/InputRegistry.java b/src/main/java/org/elasticsearch/watcher/input/InputRegistry.java index 4be6ab8f980..4be5cce56b2 100644 --- a/src/main/java/org/elasticsearch/watcher/input/InputRegistry.java +++ b/src/main/java/org/elasticsearch/watcher/input/InputRegistry.java @@ -34,19 +34,32 @@ public class InputRegistry { public ExecutableInput parse(String watchId, XContentParser parser) throws IOException { String type = null; + if (parser.currentToken() != XContentParser.Token.START_OBJECT) { + throw new InputException("could not parse input for watch [{}]. expected an object representing the input, but found [{}] instead", watchId, parser.currentToken()); + } + XContentParser.Token token; ExecutableInput input = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { type = parser.currentName(); - } else if (token == XContentParser.Token.START_OBJECT && type != null) { + } else if (type == null) { + throw new InputException("could not parse input for watch [{}]. expected field indicating the input type, but found [{}] instead", watchId, token); + } else if (token == XContentParser.Token.START_OBJECT) { InputFactory factory = factories.get(type); if (factory == null) { throw new InputException("could not parse input for watch [{}]. unknown input type [{}]", watchId, type); } input = factory.parseExecutable(watchId, parser); + } else { + throw new InputException("could not parse input for watch [{}]. expected an object representing input [{}], but found [{}] instead", watchId, type, token); } } + + if (input == null) { + throw new InputException("could not parse input for watch [{}]. expected field indicating the input type, but found an empty object instead", watchId, token); + } + return input; } diff --git a/src/test/java/org/elasticsearch/watcher/input/InputRegistryTests.java b/src/test/java/org/elasticsearch/watcher/input/InputRegistryTests.java new file mode 100644 index 00000000000..1fe838bc127 --- /dev/null +++ b/src/test/java/org/elasticsearch/watcher/input/InputRegistryTests.java @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.watcher.input; + +import org.elasticsearch.common.collect.ImmutableMap; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.test.ElasticsearchTestCase; +import org.junit.Test; + +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; + +/** + * + */ +public class InputRegistryTests extends ElasticsearchTestCase { + + @Test(expected = InputException.class) + public void testParse_EmptyInput() throws Exception { + InputRegistry registry = new InputRegistry(ImmutableMap.of()); + XContentParser parser = JsonXContent.jsonXContent.createParser( + jsonBuilder().startObject().endObject().bytes()); + parser.nextToken(); + registry.parse("_id", parser); + fail("expecting an exception when trying to parse an empty input"); + } + + @Test(expected = InputException.class) + public void testParse_ArrayInput() throws Exception { + InputRegistry registry = new InputRegistry(ImmutableMap.of()); + XContentParser parser = JsonXContent.jsonXContent.createParser( + jsonBuilder().startArray().endArray().bytes()); + parser.nextToken(); + registry.parse("_id", parser); + fail("expecting an exception when trying to parse an input that is not an object"); + } +}