@Override public void handle(ErrorContext context) { final List<LuceneWork> failingOperations = context.getFailingOperations(); final LuceneWork primaryFailure = context.getOperationAtFault(); final Throwable exceptionThatOccurred = context.getThrowable(); final StringBuilder errorMsg = new StringBuilder(); if ( exceptionThatOccurred != null ) { errorMsg.append( "Exception occurred " ) .append( exceptionThatOccurred ) .append( "\n" ); } if ( primaryFailure != null ) { errorMsg.append( "Primary Failure:\n" ); appendFailureMessage( errorMsg, primaryFailure ); } if ( ! failingOperations.isEmpty() ) { errorMsg.append( "Subsequent failures:\n" ); for ( LuceneWork workThatFailed : failingOperations ) { appendFailureMessage( errorMsg, workThatFailed ); } } handleException( errorMsg.toString(), exceptionThatOccurred ); }
private boolean shouldHandle(ErrorContext context) { if (!(context.getIndexManager() instanceof AffinityIndexManager)) { return false; } Throwable throwable = context.getThrowable(); return throwable instanceof LockObtainFailedException || throwable instanceof SearchException && throwable.getCause() instanceof InvalidLockException; } }
private List<LuceneWork> extractFailedWorks(ErrorContext errorContext) { List<LuceneWork> failingOperations = errorContext.getFailingOperations(); LuceneWork operationAtFault = errorContext.getOperationAtFault(); List<LuceneWork> failed = new ArrayList<>(failingOperations); failed.add(operationAtFault); return failed; }
@Override public void handle(ErrorContext context) { faulty.compareAndSet(null, new ThrowableWrapper(context.getOperationAtFault().toString(), context.getThrowable())); }
@Override public void handle(ErrorContext context) { register( context.getThrowable() ); } @Override
@Override public void handle(ErrorContext context) { indexManager = context.getIndexManager(); super.handle( context ); }
private List<LuceneWork> extractFailedWorks(ErrorContext errorContext) { List<LuceneWork> failingOperations = errorContext.getFailingOperations(); LuceneWork operationAtFault = errorContext.getOperationAtFault(); List<LuceneWork> failed = new ArrayList<>(failingOperations); failed.add(operationAtFault); return failed; }
@Test public void testIndexingWithStrictField() { // This property should be mapped with dynamic: strict, this means that we cannot change the value adding new // properties and therefore an error should occurs ElasticsearchDynamicIndexedValueHolder holder = new ElasticsearchDynamicIndexedValueHolder( "2" ) .strictProperty( "age", "64" ) .strictProperty( "name", "Gimli" ) .strictProperty( "race", "dwarf" ); helper.index( holder ); TestExceptionHandler errorHandler = getErrorHandler(); assertThat( errorHandler.getHandleInvocations() ).hasSize( 1 ); ErrorContext errorContext = errorHandler.getHandleInvocations().get( 0 ); Throwable throwable = errorContext.getThrowable(); assertThat( throwable ).isInstanceOf( SearchException.class ); assertThat( throwable.getMessage() ).startsWith( "HSEARCH400007" ); assertThat( throwable.getMessage() ).contains( "strict_dynamic_mapping_exception" ); assertThat( throwable.getMessage() ).contains( "strictField" ); }
@Override protected boolean errorOccurred(ErrorContext context) { if (!this.shouldHandle(context)) { return false; } AffinityIndexManager affinityIndexManager = (AffinityIndexManager) context.getIndexManager(); ShardAddress localShardAddress = affinityIndexManager.getLocalShardAddress(); List<LuceneWork> failed = this.extractFailedWorks(context); this.clearLockIfNeeded(affinityIndexManager); log.debugf("Retrying operations %s at %s", failed, affinityIndexManager.getLocalShardAddress()); CompletableFuture.supplyAsync(() -> { affinityIndexManager.performOperations(failed, null, true, true); return null; }, asyncExecutor).whenComplete((aVoid, error) -> { if (error == null) { log.debugf("Operation %s completed at %s", failed, localShardAddress); } else { log.errorf(error, "Error reapplying operation %s at %s", failed, localShardAddress); } }); return true; }
@Override public void handle(ErrorContext context) { final List<LuceneWork> failingOperations = context.getFailingOperations(); final LuceneWork primaryFailure = context.getOperationAtFault(); final Throwable exceptionThatOccurred = context.getThrowable(); final StringBuilder errorMsg = new StringBuilder(); if ( exceptionThatOccurred != null ) { errorMsg.append( "Exception occurred " ) .append( exceptionThatOccurred ) .append( "\n" ); } if ( primaryFailure != null ) { errorMsg.append( "Primary Failure:\n" ); appendFailureMessage( errorMsg, primaryFailure ); } if ( ! failingOperations.isEmpty() ) { errorMsg.append( "Subsequent failures:\n" ); for ( LuceneWork workThatFailed : failingOperations ) { appendFailureMessage( errorMsg, workThatFailed ); } } handleException( errorMsg.toString(), exceptionThatOccurred ); }
private boolean shouldHandle(ErrorContext context) { if (!(context.getIndexManager() instanceof AffinityIndexManager)) { return false; } Throwable throwable = context.getThrowable(); return throwable instanceof LockObtainFailedException || throwable instanceof SearchException && throwable.getCause() instanceof InvalidLockException; } }
@Override protected boolean errorOccurred(ErrorContext context) { if (!this.shouldHandle(context)) { return false; } AffinityIndexManager affinityIndexManager = (AffinityIndexManager) context.getIndexManager(); ShardAddress localShardAddress = affinityIndexManager.getLocalShardAddress(); List<LuceneWork> failed = this.extractFailedWorks(context); this.clearLockIfNeeded(affinityIndexManager); log.debugf("Retrying operations %s at %s", failed, affinityIndexManager.getLocalShardAddress()); CompletableFuture.supplyAsync(() -> { affinityIndexManager.performOperations(failed, null, true, true); return null; }, asyncExecutor).whenComplete((aVoid, error) -> { if (error == null) { log.debugf("Operation %s completed at %s", failed, localShardAddress); } else { log.errorf(error, "Error reapplying operation %s at %s", failed, localShardAddress); } }); return true; }
@Test public void singleError() { Capture<ErrorContext> capture = newCapture(); replay(); DefaultContextualErrorHandler handler = new DefaultContextualErrorHandler( errorHandlerMock ); verify(); Throwable throwable = new Throwable(); reset(); expect( work1.getLuceneWork() ).andReturn( luceneWork1 ); expect( work2.getLuceneWork() ).andReturn( luceneWork2 ); expect( work3.getLuceneWork() ).andReturn( luceneWork3 ); replay(); handler.markAsFailed( work1, throwable ); handler.markAsSkipped( work2 ); handler.markAsSkipped( work3 ); verify(); reset(); errorHandlerMock.handle( capture( capture ) ); replay(); handler.handle(); verify(); ErrorContext errorContext = capture.getValue(); assertThat( errorContext.getThrowable() ).isSameAs( throwable ); assertThat( errorContext.getOperationAtFault() ).isSameAs( luceneWork1 ); assertThat( errorContext.getFailingOperations() ).containsExactlyInAnyOrder( luceneWork1, luceneWork2, luceneWork3 ); }
@Test public void multipleErrors_works() { Capture<ErrorContext> capture = newCapture(); replay(); DefaultContextualErrorHandler handler = new DefaultContextualErrorHandler( errorHandlerMock ); verify(); Throwable throwable1 = new Throwable(); Throwable throwable2 = new Throwable(); reset(); expect( work1.getLuceneWork() ).andReturn( luceneWork1 ); expect( work2.getLuceneWork() ).andReturn( luceneWork2 ); expect( work3.getLuceneWork() ).andReturn( luceneWork3 ); replay(); handler.markAsFailed( work1, throwable1 ); handler.markAsFailed( work2, throwable2 ); handler.markAsSkipped( work3 ); verify(); reset(); errorHandlerMock.handle( capture( capture ) ); replay(); handler.handle(); verify(); ErrorContext errorContext = capture.getValue(); assertThat( errorContext.getThrowable() ).isSameAs( throwable1 ); assertThat( throwable1.getSuppressed() ).containsExactlyInAnyOrder( throwable2 ); assertThat( errorContext.getOperationAtFault() ).isIn( luceneWork1, luceneWork2 ); assertThat( errorContext.getFailingOperations() ).containsExactlyInAnyOrder( luceneWork1, luceneWork2, luceneWork3 ); }
verify(); ErrorContext errorContext = capture.getValue(); assertThat( errorContext.getThrowable() ).isSameAs( throwable ); assertThat( errorContext.getOperationAtFault() ).isNull(); assertThat( errorContext.getFailingOperations() ).containsExactlyInAnyOrder( luceneWork1, luceneWork2, luceneWork3 );
verify(); ErrorContext errorContext = capture.getValue(); assertThat( errorContext.getThrowable() ).isSameAs( throwable1 ); assertThat( throwable1.getSuppressed() ).containsExactlyInAnyOrder( throwable2 ); assertThat( errorContext.getOperationAtFault() ).isSameAs( luceneWork1 ); assertThat( errorContext.getFailingOperations() ).containsExactlyInAnyOrder( luceneWork1, luceneWork2, luceneWork3 );