Skip to content

Commit a1918c2

Browse files
authored
LOG4J2-2659: AbstractAction handles unchecked RuntimeException and Error (#296)
1 parent c97591b commit a1918c2

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractAction.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ public synchronized void run() {
6464
if (!interrupted) {
6565
try {
6666
execute();
67-
} catch (final IOException ex) {
67+
} catch (final RuntimeException | IOException ex) {
6868
reportException(ex);
69+
} catch (final Error e) {
70+
// reportException takes Exception, widening to Throwable would break custom implementations
71+
// so we wrap Errors in RuntimeException for handling.
72+
reportException(new RuntimeException(e));
6973
}
7074

7175
complete = true;

log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractActionTest.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,46 @@ public void testExceptionsAreLoggedToStatusLogger() {
3535
"$TestAction.execute(AbstractActionTest.java:"));
3636
}
3737

38+
@Test
39+
public void testRuntimeExceptionsAreLoggedToStatusLogger() {
40+
StatusLogger statusLogger = StatusLogger.getLogger();
41+
statusLogger.clear();
42+
new AbstractAction() {
43+
@Override
44+
public boolean execute() {
45+
throw new IllegalStateException();
46+
}
47+
}.run();
48+
List<StatusData> statusDataList = statusLogger.getStatusData();
49+
assertEquals(1, statusDataList.size());
50+
StatusData statusData = statusDataList.get(0);
51+
assertEquals(Level.WARN, statusData.getLevel());
52+
String formattedMessage = statusData.getFormattedStatus();
53+
assertTrue(formattedMessage.contains("Exception reported by action"));
54+
}
55+
56+
@Test
57+
public void testErrorsAreLoggedToStatusLogger() {
58+
StatusLogger statusLogger = StatusLogger.getLogger();
59+
statusLogger.clear();
60+
new AbstractAction() {
61+
@Override
62+
public boolean execute() {
63+
throw new AssertionError();
64+
}
65+
}.run();
66+
List<StatusData> statusDataList = statusLogger.getStatusData();
67+
assertEquals(1, statusDataList.size());
68+
StatusData statusData = statusDataList.get(0);
69+
assertEquals(Level.WARN, statusData.getLevel());
70+
String formattedMessage = statusData.getFormattedStatus();
71+
assertTrue(formattedMessage.contains("Exception reported by action"));
72+
}
73+
3874
private static final class TestAction extends AbstractAction {
3975
@Override
40-
public boolean execute() {
41-
this.reportException(new IOException("failed"));
42-
return false;
76+
public boolean execute() throws IOException {
77+
throw new IOException("failed");
4378
}
4479
}
45-
}
80+
}

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@
158158
AbstractAction.reportException records a warning to the status logger, providing more information when file
159159
based appenders fail to compress rolled data asynchronously.
160160
</action>
161+
<action issue="LOG4J2-2659" dev="ckozak" type="fix">
162+
AbstractAction handles and records unchecked RuntimeException and Error in addition to IOException.
163+
</action>
161164
</release>
162165
<release version="2.12.0" date="2019-06-23" description="GA Release 2.12.0">
163166
<action issue="LOG4J2-2547" dev="rgoers" type="fix">

0 commit comments

Comments
 (0)