mirror of
https://github.com/apache/druid.git
synced 2025-02-17 07:25:02 +00:00
Introduce standardized "Resource limit exceeded" error. (#3338)
Fixes #3336.
This commit is contained in:
parent
21bce96c4c
commit
8899affe48
@ -97,4 +97,5 @@ Possible codes for the *error* field include:
|
||||
|`Query timeout`|The query timed out.|
|
||||
|`Query interrupted`|The query was interrupted, possibly due to JVM shutdown.|
|
||||
|`Query cancelled`|The query was cancelled through the query cancellation API.|
|
||||
|`Resource limit exceeded`|The query exceeded a configured resource limit (e.g. groupBy maxResults).|
|
||||
|`Unknown exception`|Some other exception occurred. Check errorMessage and errorClass for details, although keep in mind that the contents of those fields are free-form and may change from release to release.|
|
||||
|
@ -44,6 +44,7 @@ public class QueryInterruptedException extends RuntimeException
|
||||
public static final String QUERY_INTERRUPTED = "Query interrupted";
|
||||
public static final String QUERY_TIMEOUT = "Query timeout";
|
||||
public static final String QUERY_CANCELLED = "Query cancelled";
|
||||
public static final String RESOURCE_LIMIT_EXCEEDED = "Resource limit exceeded";
|
||||
public static final String UNKNOWN_EXCEPTION = "Unknown exception";
|
||||
|
||||
private final String errorCode;
|
||||
@ -118,6 +119,8 @@ public class QueryInterruptedException extends RuntimeException
|
||||
return QUERY_CANCELLED;
|
||||
} else if (e instanceof TimeoutException) {
|
||||
return QUERY_TIMEOUT;
|
||||
} else if (e instanceof ResourceLimitExceededException) {
|
||||
return RESOURCE_LIMIT_EXCEEDED;
|
||||
} else {
|
||||
return UNKNOWN_EXCEPTION;
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Metamarkets licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package io.druid.query;
|
||||
|
||||
/**
|
||||
* Exception indicating that an operation failed because it exceeded some configured resource limit.
|
||||
*
|
||||
* This is used as a marker exception by {@link QueryInterruptedException} to report the "Resource limit exceeded"
|
||||
* error code.
|
||||
*/
|
||||
public class ResourceLimitExceededException extends RuntimeException
|
||||
{
|
||||
public ResourceLimitExceededException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ import io.druid.data.input.MapBasedInputRow;
|
||||
import io.druid.data.input.MapBasedRow;
|
||||
import io.druid.data.input.Row;
|
||||
import io.druid.granularity.QueryGranularity;
|
||||
import io.druid.query.ResourceLimitExceededException;
|
||||
import io.druid.query.aggregation.AggregatorFactory;
|
||||
import io.druid.query.dimension.DimensionSpec;
|
||||
import io.druid.segment.incremental.IncrementalIndex;
|
||||
@ -132,7 +133,7 @@ public class GroupByQueryHelper
|
||||
);
|
||||
}
|
||||
catch (IndexSizeExceededException e) {
|
||||
throw new ISE(e.getMessage());
|
||||
throw new ResourceLimitExceededException(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
throw new ISE("Unable to accumulate something of type [%s]", in.getClass());
|
||||
|
@ -50,6 +50,7 @@ import io.druid.query.QueryContextKeys;
|
||||
import io.druid.query.QueryInterruptedException;
|
||||
import io.druid.query.QueryRunner;
|
||||
import io.druid.query.QueryWatcher;
|
||||
import io.druid.query.ResourceLimitExceededException;
|
||||
import io.druid.query.aggregation.AggregatorFactory;
|
||||
import io.druid.query.groupby.GroupByQuery;
|
||||
import io.druid.query.groupby.GroupByQueryConfig;
|
||||
@ -308,7 +309,7 @@ public class GroupByMergingQueryRunnerV2 implements QueryRunner
|
||||
for (Boolean result : results) {
|
||||
if (!result) {
|
||||
future.cancel(true);
|
||||
throw new ISE("Grouping resources exhausted");
|
||||
throw new ResourceLimitExceededException("Grouping resources exhausted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,10 @@ public class QueryInterruptedExceptionTest
|
||||
Assert.assertEquals("Query timeout", new QueryInterruptedException(new TimeoutException()).getErrorCode());
|
||||
Assert.assertEquals("Unknown exception", new QueryInterruptedException(null).getErrorCode());
|
||||
Assert.assertEquals("Unknown exception", new QueryInterruptedException(new ISE("Something bad!")).getErrorCode());
|
||||
Assert.assertEquals(
|
||||
"Resource limit exceeded",
|
||||
new QueryInterruptedException(new ResourceLimitExceededException("too many!")).getErrorCode()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"Unknown exception",
|
||||
new QueryInterruptedException(new QueryInterruptedException(new ISE("Something bad!"))).getErrorCode()
|
||||
@ -74,6 +78,10 @@ public class QueryInterruptedExceptionTest
|
||||
null,
|
||||
new QueryInterruptedException(null).getMessage()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"too many!",
|
||||
new QueryInterruptedException(new ResourceLimitExceededException("too many!")).getMessage()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"Something bad!",
|
||||
new QueryInterruptedException(new ISE("Something bad!")).getMessage()
|
||||
@ -103,6 +111,10 @@ public class QueryInterruptedExceptionTest
|
||||
"java.util.concurrent.TimeoutException",
|
||||
new QueryInterruptedException(new TimeoutException()).getErrorClass()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"io.druid.query.ResourceLimitExceededException",
|
||||
new QueryInterruptedException(new ResourceLimitExceededException("too many!")).getErrorClass()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
null,
|
||||
new QueryInterruptedException(null).getErrorClass()
|
||||
|
@ -50,6 +50,7 @@ import io.druid.query.Query;
|
||||
import io.druid.query.QueryRunner;
|
||||
import io.druid.query.QueryRunnerTestHelper;
|
||||
import io.druid.query.QueryToolChest;
|
||||
import io.druid.query.ResourceLimitExceededException;
|
||||
import io.druid.query.Result;
|
||||
import io.druid.query.aggregation.AggregatorFactory;
|
||||
import io.druid.query.aggregation.CountAggregatorFactory;
|
||||
@ -875,7 +876,7 @@ public class GroupByQueryRunnerTest
|
||||
|
||||
List<Row> expectedResults = null;
|
||||
if (config.getDefaultStrategy().equals(GroupByStrategySelector.STRATEGY_V1)) {
|
||||
expectedException.expect(ISE.class);
|
||||
expectedException.expect(ResourceLimitExceededException.class);
|
||||
} else {
|
||||
expectedResults = Arrays.asList(
|
||||
GroupByQueryRunnerTestHelper.createExpectedRow("2011-04-01", "alias", "automotive", "rows", 1L, "idx", 135L),
|
||||
@ -968,7 +969,7 @@ public class GroupByQueryRunnerTest
|
||||
|
||||
List<Row> expectedResults = null;
|
||||
if (config.getDefaultStrategy().equals(GroupByStrategySelector.STRATEGY_V2)) {
|
||||
expectedException.expect(ISE.class);
|
||||
expectedException.expect(ResourceLimitExceededException.class);
|
||||
expectedException.expectMessage("Grouping resources exhausted");
|
||||
} else {
|
||||
expectedResults = Arrays.asList(
|
||||
|
Loading…
x
Reference in New Issue
Block a user