[Transform] improve irrecoverable error detection
treat resource not found and illegal argument exceptions as irrecoverable error relates #50135
This commit is contained in:
parent
ba2810f23d
commit
5d5f3ce256
|
@ -174,7 +174,7 @@ class ClientTransformIndexer extends TransformIndexer {
|
||||||
// Determine whether the failure is irrecoverable (transform should go into failed state) or not (transform increments
|
// Determine whether the failure is irrecoverable (transform should go into failed state) or not (transform increments
|
||||||
// the indexing failure counter
|
// the indexing failure counter
|
||||||
// and possibly retries)
|
// and possibly retries)
|
||||||
Exception irrecoverableException = ExceptionRootCauseFinder.getFirstIrrecoverableExceptionFromBulkResponses(
|
Throwable irrecoverableException = ExceptionRootCauseFinder.getFirstIrrecoverableExceptionFromBulkResponses(
|
||||||
deduplicatedFailures.values()
|
deduplicatedFailures.values()
|
||||||
);
|
);
|
||||||
if (irrecoverableException == null) {
|
if (irrecoverableException == null) {
|
||||||
|
@ -373,7 +373,7 @@ class ClientTransformIndexer extends TransformIndexer {
|
||||||
return failureMessage;
|
return failureMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Exception decorateBulkIndexException(Exception irrecoverableException) {
|
private static Throwable decorateBulkIndexException(Throwable irrecoverableException) {
|
||||||
if (irrecoverableException instanceof MapperParsingException) {
|
if (irrecoverableException instanceof MapperParsingException) {
|
||||||
return new TransformException(
|
return new TransformException(
|
||||||
"Destination index mappings are incompatible with the transform configuration.",
|
"Destination index mappings are incompatible with the transform configuration.",
|
||||||
|
|
|
@ -484,28 +484,30 @@ public abstract class TransformIndexer extends AsyncTwoPhaseIndexer<TransformInd
|
||||||
handleIrrecoverableBulkIndexingException((BulkIndexingException) unwrappedException);
|
handleIrrecoverableBulkIndexingException((BulkIndexingException) unwrappedException);
|
||||||
} else if (unwrappedException instanceof IndexNotFoundException
|
} else if (unwrappedException instanceof IndexNotFoundException
|
||||||
|| unwrappedException instanceof AggregationResultUtils.AggregationExtractionException
|
|| unwrappedException instanceof AggregationResultUtils.AggregationExtractionException
|
||||||
|| unwrappedException instanceof TransformConfigReloadingException) {
|
|| unwrappedException instanceof TransformConfigReloadingException
|
||||||
failIndexer("task encountered irrecoverable failure: " + e.getMessage());
|
|| unwrappedException instanceof ResourceNotFoundException
|
||||||
} else if (context.getAndIncrementFailureCount() > context.getNumFailureRetries()) {
|
|| unwrappedException instanceof IllegalArgumentException) {
|
||||||
failIndexer(
|
failIndexer("task encountered irrecoverable failure: " + e.getMessage());
|
||||||
"task encountered more than "
|
} else if (context.getAndIncrementFailureCount() > context.getNumFailureRetries()) {
|
||||||
+ context.getNumFailureRetries()
|
failIndexer(
|
||||||
+ " failures; latest failure: "
|
"task encountered more than "
|
||||||
+ ExceptionRootCauseFinder.getDetailedMessage(unwrappedException)
|
+ context.getNumFailureRetries()
|
||||||
);
|
+ " failures; latest failure: "
|
||||||
} else {
|
+ ExceptionRootCauseFinder.getDetailedMessage(unwrappedException)
|
||||||
// Since our schedule fires again very quickly after failures it is possible to run into the same failure numerous
|
|
||||||
// times in a row, very quickly. We do not want to spam the audit log with repeated failures, so only record the first one
|
|
||||||
if (e.getMessage().equals(lastAuditedExceptionMessage) == false) {
|
|
||||||
String message = ExceptionRootCauseFinder.getDetailedMessage(unwrappedException);
|
|
||||||
|
|
||||||
auditor.warning(
|
|
||||||
getJobId(),
|
|
||||||
"Transform encountered an exception: " + message + " Will attempt again at next scheduled trigger."
|
|
||||||
);
|
);
|
||||||
lastAuditedExceptionMessage = message;
|
} else {
|
||||||
|
// Since our schedule fires again very quickly after failures it is possible to run into the same failure numerous
|
||||||
|
// times in a row, very quickly. We do not want to spam the audit log with repeated failures, so only record the first one
|
||||||
|
if (e.getMessage().equals(lastAuditedExceptionMessage) == false) {
|
||||||
|
String message = ExceptionRootCauseFinder.getDetailedMessage(unwrappedException);
|
||||||
|
|
||||||
|
auditor.warning(
|
||||||
|
getJobId(),
|
||||||
|
"Transform encountered an exception: " + message + " Will attempt again at next scheduled trigger."
|
||||||
|
);
|
||||||
|
lastAuditedExceptionMessage = message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.elasticsearch.xpack.transform.utils;
|
package org.elasticsearch.xpack.transform.utils;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
import org.elasticsearch.ResourceNotFoundException;
|
||||||
import org.elasticsearch.action.bulk.BulkItemResponse;
|
import org.elasticsearch.action.bulk.BulkItemResponse;
|
||||||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||||
import org.elasticsearch.action.search.ShardSearchFailure;
|
import org.elasticsearch.action.search.ShardSearchFailure;
|
||||||
|
@ -63,10 +64,13 @@ public final class ExceptionRootCauseFinder {
|
||||||
* @param failures a collection of bulk item responses
|
* @param failures a collection of bulk item responses
|
||||||
* @return The first exception considered irrecoverable if there are any, null if no irrecoverable exception found
|
* @return The first exception considered irrecoverable if there are any, null if no irrecoverable exception found
|
||||||
*/
|
*/
|
||||||
public static Exception getFirstIrrecoverableExceptionFromBulkResponses(Collection<BulkItemResponse> failures) {
|
public static Throwable getFirstIrrecoverableExceptionFromBulkResponses(Collection<BulkItemResponse> failures) {
|
||||||
for (BulkItemResponse failure : failures) {
|
for (BulkItemResponse failure : failures) {
|
||||||
if (failure.getFailure().getCause() instanceof MapperParsingException) {
|
Throwable unwrappedThrowable = org.elasticsearch.ExceptionsHelper.unwrapCause(failure.getFailure().getCause());
|
||||||
return failure.getFailure().getCause();
|
if (unwrappedThrowable instanceof MapperParsingException
|
||||||
|
|| unwrappedThrowable instanceof IllegalArgumentException
|
||||||
|
|| unwrappedThrowable instanceof ResourceNotFoundException) {
|
||||||
|
return unwrappedThrowable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue