@@ -1562,23 +1562,15 @@ public IndexCommitRef acquireIndexCommit(final boolean flushFirst) throws Engine
1562
1562
}
1563
1563
}
1564
1564
1565
- @ SuppressWarnings ("finally" )
1566
1565
private boolean failOnTragicEvent (AlreadyClosedException ex ) {
1567
1566
final boolean engineFailed ;
1568
1567
// if we are already closed due to some tragic exception
1569
1568
// we need to fail the engine. it might have already been failed before
1570
1569
// but we are double-checking it's failed and closed
1571
1570
if (indexWriter .isOpen () == false && indexWriter .getTragicException () != null ) {
1572
- if (indexWriter .getTragicException () instanceof Error ) {
1573
- try {
1574
- logger .error ("tragic event in index writer" , ex );
1575
- } finally {
1576
- throw (Error ) indexWriter .getTragicException ();
1577
- }
1578
- } else {
1579
- failEngine ("already closed by tragic event on the index writer" , (Exception ) indexWriter .getTragicException ());
1580
- engineFailed = true ;
1581
- }
1571
+ maybeDie ("tragic event in index writer" , indexWriter .getTragicException ());
1572
+ failEngine ("already closed by tragic event on the index writer" , (Exception ) indexWriter .getTragicException ());
1573
+ engineFailed = true ;
1582
1574
} else if (translog .isOpen () == false && translog .getTragicException () != null ) {
1583
1575
failEngine ("already closed by tragic event on the translog" , translog .getTragicException ());
1584
1576
engineFailed = true ;
@@ -1889,7 +1881,6 @@ protected void doRun() throws Exception {
1889
1881
1890
1882
@ Override
1891
1883
protected void handleMergeException (final Directory dir , final Throwable exc ) {
1892
- logger .error ("failed to merge" , exc );
1893
1884
engineConfig .getThreadPool ().generic ().execute (new AbstractRunnable () {
1894
1885
@ Override
1895
1886
public void onFailure (Exception e ) {
@@ -1898,13 +1889,39 @@ public void onFailure(Exception e) {
1898
1889
1899
1890
@ Override
1900
1891
protected void doRun () throws Exception {
1901
- MergePolicy .MergeException e = new MergePolicy .MergeException (exc , dir );
1902
- failEngine ("merge failed" , e );
1892
+ /*
1893
+ * We do this on another thread rather than the merge thread that we are initially called on so that we have complete
1894
+ * confidence that the call stack does not contain catch statements that would cause the error that might be thrown
1895
+ * here from being caught and never reaching the uncaught exception handler.
1896
+ */
1897
+ maybeDie ("fatal error while merging" , exc );
1898
+ logger .error ("failed to merge" , exc );
1899
+ failEngine ("merge failed" , new MergePolicy .MergeException (exc , dir ));
1903
1900
}
1904
1901
});
1905
1902
}
1906
1903
}
1907
1904
1905
+ /**
1906
+ * If the specified throwable is a fatal error, this throwable will be thrown. Callers should ensure that there are no catch statements
1907
+ * that would catch an error in the stack as the fatal error here should go uncaught and be handled by the uncaught exception handler
1908
+ * that we install during bootstrap. If the specified throwable is indeed a fatal error, the specified message will attempt to be logged
1909
+ * before throwing the fatal error. If the specified throwable is not a fatal error, this method is a no-op.
1910
+ *
1911
+ * @param maybeMessage the message to maybe log
1912
+ * @param maybeFatal the throwable that is maybe fatal
1913
+ */
1914
+ @ SuppressWarnings ("finally" )
1915
+ private void maybeDie (final String maybeMessage , final Throwable maybeFatal ) {
1916
+ if (maybeFatal instanceof Error ) {
1917
+ try {
1918
+ logger .error (maybeMessage , maybeFatal );
1919
+ } finally {
1920
+ throw (Error ) maybeFatal ;
1921
+ }
1922
+ }
1923
+ }
1924
+
1908
1925
/**
1909
1926
* Commits the specified index writer.
1910
1927
*
0 commit comments