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