@@ -1592,23 +1592,15 @@ public IndexCommitRef acquireIndexCommit(final boolean flushFirst) throws Engine
1592
1592
}
1593
1593
}
1594
1594
1595
- @ SuppressWarnings ("finally" )
1596
1595
private boolean failOnTragicEvent (AlreadyClosedException ex ) {
1597
1596
final boolean engineFailed ;
1598
1597
// if we are already closed due to some tragic exception
1599
1598
// we need to fail the engine. it might have already been failed before
1600
1599
// but we are double-checking it's failed and closed
1601
1600
if (indexWriter .isOpen () == false && indexWriter .getTragicException () != null ) {
1602
- if (indexWriter .getTragicException () instanceof Error ) {
1603
- try {
1604
- logger .error ("tragic event in index writer" , ex );
1605
- } finally {
1606
- throw (Error ) indexWriter .getTragicException ();
1607
- }
1608
- } else {
1609
- failEngine ("already closed by tragic event on the index writer" , (Exception ) indexWriter .getTragicException ());
1610
- engineFailed = true ;
1611
- }
1601
+ maybeDie ("tragic event in index writer" , indexWriter .getTragicException ());
1602
+ failEngine ("already closed by tragic event on the index writer" , (Exception ) indexWriter .getTragicException ());
1603
+ engineFailed = true ;
1612
1604
} else if (translog .isOpen () == false && translog .getTragicException () != null ) {
1613
1605
failEngine ("already closed by tragic event on the translog" , translog .getTragicException ());
1614
1606
engineFailed = true ;
@@ -1929,7 +1921,6 @@ protected void doRun() throws Exception {
1929
1921
1930
1922
@ Override
1931
1923
protected void handleMergeException (final Directory dir , final Throwable exc ) {
1932
- logger .error ("failed to merge" , exc );
1933
1924
engineConfig .getThreadPool ().generic ().execute (new AbstractRunnable () {
1934
1925
@ Override
1935
1926
public void onFailure (Exception e ) {
@@ -1938,13 +1929,39 @@ public void onFailure(Exception e) {
1938
1929
1939
1930
@ Override
1940
1931
protected void doRun () throws Exception {
1941
- MergePolicy .MergeException e = new MergePolicy .MergeException (exc , dir );
1942
- failEngine ("merge failed" , e );
1932
+ /*
1933
+ * We do this on another thread rather than the merge thread that we are initially called on so that we have complete
1934
+ * confidence that the call stack does not contain catch statements that would cause the error that might be thrown
1935
+ * here from being caught and never reaching the uncaught exception handler.
1936
+ */
1937
+ maybeDie ("fatal error while merging" , exc );
1938
+ logger .error ("failed to merge" , exc );
1939
+ failEngine ("merge failed" , new MergePolicy .MergeException (exc , dir ));
1943
1940
}
1944
1941
});
1945
1942
}
1946
1943
}
1947
1944
1945
+ /**
1946
+ * If the specified throwable is a fatal error, this throwable will be thrown. Callers should ensure that there are no catch statements
1947
+ * that would catch an error in the stack as the fatal error here should go uncaught and be handled by the uncaught exception handler
1948
+ * that we install during bootstrap. If the specified throwable is indeed a fatal error, the specified message will attempt to be logged
1949
+ * before throwing the fatal error. If the specified throwable is not a fatal error, this method is a no-op.
1950
+ *
1951
+ * @param maybeMessage the message to maybe log
1952
+ * @param maybeFatal the throwable that is maybe fatal
1953
+ */
1954
+ @ SuppressWarnings ("finally" )
1955
+ private void maybeDie (final String maybeMessage , final Throwable maybeFatal ) {
1956
+ if (maybeFatal instanceof Error ) {
1957
+ try {
1958
+ logger .error (maybeMessage , maybeFatal );
1959
+ } finally {
1960
+ throw (Error ) maybeFatal ;
1961
+ }
1962
+ }
1963
+ }
1964
+
1948
1965
/**
1949
1966
* Commits the specified index writer.
1950
1967
*
0 commit comments