Add logging in Exceptions.throwIf[Jvm]Fatal, add isFatal methods (#3122) · reactor/reactor-core@50bb983 (original) (raw)
1
1
`/*
`
2
``
`-
- Copyright (c) 2015-2021 VMware Inc. or its affiliates, All Rights Reserved.
`
``
2
`+
- Copyright (c) 2015-2022 VMware Inc. or its affiliates, All Rights Reserved.
`
3
3
` *
`
4
4
` * Licensed under the Apache License, Version 2.0 (the "License");
`
5
5
` * you may not use this file except in compliance with the License.
`
`@@ -23,10 +23,12 @@
`
23
23
`import java.util.concurrent.RejectedExecutionException;
`
24
24
`import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
`
25
25
``
``
26
`+
import org.assertj.core.api.SoftAssertions;
`
26
27
`import org.junit.jupiter.api.Test;
`
27
28
``
28
29
`import reactor.core.publisher.Mono;
`
29
30
`import reactor.test.util.RaceTestUtils;
`
``
31
`+
import reactor.test.util.TestLogger;
`
30
32
`import reactor.util.annotation.Nullable;
`
31
33
``
32
34
`import static org.assertj.core.api.Assertions.*;
`
`@@ -43,6 +45,32 @@ public class ExceptionsTest {
`
43
45
`static final AtomicReferenceFieldUpdater<ExceptionsTest, Throwable> ADD_THROWABLE =
`
44
46
`AtomicReferenceFieldUpdater.newUpdater(ExceptionsTest.class, Throwable.class, "addThrowable");
`
45
47
``
``
48
`+
static VirtualMachineError JVM_FATAL_VIRTUAL_MACHINE_ERROR = new VirtualMachineError("expected to be logged") {
`
``
49
`+
@Override
`
``
50
`+
public String toString() {
`
``
51
`+
return "custom VirtualMachineError: expected to be logged";
`
``
52
`+
}
`
``
53
`+
};
`
``
54
+
``
55
`+
static final ThreadDeath JVM_FATAL_THREAD_DEATH = new ThreadDeath() {
`
``
56
`+
@Override
`
``
57
`+
public String getMessage() {
`
``
58
`+
return "expected to be logged";
`
``
59
`+
}
`
``
60
+
``
61
`+
@Override
`
``
62
`+
public String toString() {
`
``
63
`+
return "custom ThreadDeath: expected to be logged";
`
``
64
`+
}
`
``
65
`+
};
`
``
66
+
``
67
`+
static final LinkageError JVM_FATAL_LINKAGE_ERROR = new LinkageError("expected to be logged") {
`
``
68
`+
@Override
`
``
69
`+
public String toString() {
`
``
70
`+
return "custom LinkageError: expected to be logged";
`
``
71
`+
}
`
``
72
`+
};
`
``
73
+
46
74
`@Test
`
47
75
`public void bubble() throws Exception {
`
48
76
`Throwable t = new Exception("test");
`
`@@ -157,44 +185,146 @@ public void propagateDoesntWrapRuntimeException() {
`
157
185
`//TODO test terminate
`
158
186
``
159
187
`@Test
`
160
``
`-
public void throwIfFatalThrowsBubbling() {
`
161
``
`-
BubblingException expected = new BubblingException("expected");
`
``
188
`+
void bubblingExceptionIsFatalButNotJvmFatal() {
`
``
189
`+
Throwable exception = new BubblingException("expected");
`
``
190
`+
assertThat(Exceptions.isFatal(exception))
`
``
191
`+
.as("isFatal(bubbling)")
`
``
192
`+
.isTrue();
`
``
193
`+
assertThat(Exceptions.isJvmFatal(exception))
`
``
194
`+
.as("isJvmFatal(bubbling)")
`
``
195
`+
.isFalse();
`
``
196
`+
}
`
``
197
+
``
198
`+
@Test
`
``
199
`+
void errorCallbackNotImplementedIsFatalButNotJvmFatal() {
`
``
200
`+
Throwable exception = new ErrorCallbackNotImplemented(new IllegalStateException("expected cause"));
`
``
201
`+
assertThat(Exceptions.isFatal(exception))
`
``
202
`+
.as("isFatal(ErrorCallbackNotImplemented)")
`
``
203
`+
.isTrue();
`
``
204
`+
assertThat(Exceptions.isJvmFatal(exception))
`
``
205
`+
.as("isJvmFatal(ErrorCallbackNotImplemented)")
`
``
206
`+
.isFalse();
`
``
207
`+
}
`
``
208
+
``
209
`+
@Test
`
``
210
`+
void virtualMachineErrorIsFatalAndJvmFatal() {
`
``
211
`+
assertThat(Exceptions.isFatal(JVM_FATAL_VIRTUAL_MACHINE_ERROR))
`
``
212
`+
.as("isFatal(VirtualMachineError)")
`
``
213
`+
.isTrue();
`
``
214
`+
assertThat(Exceptions.isJvmFatal(JVM_FATAL_VIRTUAL_MACHINE_ERROR))
`
``
215
`+
.as("isJvmFatal(VirtualMachineError)")
`
``
216
`+
.isTrue();
`
``
217
`+
}
`
``
218
+
``
219
`+
@Test
`
``
220
`+
void linkageErrorIsFatalAndJvmFatal() {
`
``
221
`+
assertThat(Exceptions.isFatal(JVM_FATAL_LINKAGE_ERROR))
`
``
222
`+
.as("isFatal(LinkageError)")
`
``
223
`+
.isTrue();
`
``
224
`+
assertThat(Exceptions.isJvmFatal(JVM_FATAL_LINKAGE_ERROR))
`
``
225
`+
.as("isJvmFatal(LinkageError)")
`
``
226
`+
.isTrue();
`
``
227
`+
}
`
``
228
+
``
229
`+
@Test
`
``
230
`+
void threadDeathIsFatalAndJvmFatal() {
`
``
231
`+
assertThat(Exceptions.isFatal(JVM_FATAL_THREAD_DEATH))
`
``
232
`+
.as("isFatal(ThreadDeath)")
`
``
233
`+
.isTrue();
`
``
234
`+
assertThat(Exceptions.isJvmFatal(JVM_FATAL_THREAD_DEATH))
`
``
235
`+
.as("isJvmFatal(ThreadDeath)")
`
``
236
`+
.isTrue();
`
``
237
`+
}
`
``
238
+
``
239
`+
@Test
`
``
240
`+
@TestLoggerExtension.Redirect
`
``
241
`+
void throwIfFatalThrowsAndLogsBubbling(TestLogger testLogger) {
`
``
242
`+
BubblingException expected = new BubblingException("expected to be logged");
`
162
243
``
163
244
`assertThatExceptionOfType(BubblingException.class)
`
164
245
` .isThrownBy(() -> Exceptions.throwIfFatal(expected))
`
165
246
` .isSameAs(expected);
`
``
247
+
``
248
`+
assertThat(testLogger.getErrContent())
`
``
249
`+
.startsWith("[ WARN] throwIfFatal detected a fatal exception, which is thrown and logged below: - reactor.core.Exceptions$BubblingException: expected to be logged");
`
166
250
` }
`
167
251
``
168
252
`@Test
`
169
``
`-
public void throwIfFatalThrowsErrorCallbackNotImplemented() {
`
170
``
`-
ErrorCallbackNotImplemented expected = new ErrorCallbackNotImplemented(new IllegalStateException("expected cause"));
`
``
253
`+
@TestLoggerExtension.Redirect
`
``
254
`+
void throwIfFatalThrowsAndLogsErrorCallbackNotImplemented(TestLogger testLogger) {
`
``
255
`+
ErrorCallbackNotImplemented expected = new ErrorCallbackNotImplemented(new IllegalStateException("expected to be logged"));
`
171
256
``
172
257
`assertThatExceptionOfType(ErrorCallbackNotImplemented.class)
`
173
258
` .isThrownBy(() -> Exceptions.throwIfFatal(expected))
`
174
259
` .isSameAs(expected)
`
175
260
` .withCause(expected.getCause());
`
``
261
+
``
262
`+
assertThat(testLogger.getErrContent())
`
``
263
`+
.startsWith("[ WARN] throwIfFatal detected a fatal exception, which is thrown and logged below: - reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: expected to be logged");
`
176
264
` }
`
177
265
``
178
266
`@Test
`
179
``
`-
public void throwIfJvmFatal() {
`
180
``
`-
VirtualMachineError fatal1 = new VirtualMachineError() {};
`
181
``
`-
ThreadDeath fatal2 = new ThreadDeath();
`
182
``
`-
LinkageError fatal3 = new LinkageError();
`
``
267
`+
@TestLoggerExtension.Redirect
`
``
268
`+
void throwIfFatalWithJvmFatalErrorsDoesThrowAndLog(TestLogger testLogger) {
`
``
269
`+
SoftAssertions.assertSoftly(softly -> {
`
``
270
`+
softly.assertThatExceptionOfType(VirtualMachineError.class)
`
``
271
`+
.as("VirtualMachineError")
`
``
272
`+
.isThrownBy(() -> Exceptions.throwIfFatal(JVM_FATAL_VIRTUAL_MACHINE_ERROR))
`
``
273
`+
.isSameAs(JVM_FATAL_VIRTUAL_MACHINE_ERROR);
`
183
274
``
``
275
`+
softly.assertThatExceptionOfType(ThreadDeath.class)
`
``
276
`+
.as("ThreadDeath")
`
``
277
`+
.isThrownBy(() -> Exceptions.throwIfFatal(JVM_FATAL_THREAD_DEATH))
`
``
278
`+
.isSameAs(JVM_FATAL_THREAD_DEATH);
`
``
279
+
``
280
`+
softly.assertThatExceptionOfType(LinkageError.class)
`
``
281
`+
.as("LinkageError")
`
``
282
`+
.isThrownBy(() -> Exceptions.throwIfFatal(JVM_FATAL_LINKAGE_ERROR))
`
``
283
`+
.isSameAs(JVM_FATAL_LINKAGE_ERROR);
`
``
284
+
``
285
`+
softly.assertThat(testLogger.getErrContent())
`
``
286
`+
.startsWith("[ WARN] throwIfFatal detected a jvm fatal exception, which is thrown and logged below: - custom VirtualMachineError: expected to be logged")
`
``
287
`+
.contains("[ WARN] throwIfFatal detected a jvm fatal exception, which is thrown and logged below: - custom ThreadDeath: expected to be logged")
`
``
288
`+
.contains("[ WARN] throwIfFatal detected a jvm fatal exception, which is thrown and logged below: - custom LinkageError: expected to be logged");
`
``
289
`+
});
`
``
290
`+
}
`
``
291
+
``
292
`+
@Test
`
``
293
`+
@TestLoggerExtension.Redirect
`
``
294
`+
void throwIfJvmFatalDoesThrowAndLog(TestLogger testLogger) {
`
184
295
`assertThatExceptionOfType(VirtualMachineError.class)
`
185
296
` .as("VirtualMachineError")
`
186
``
`-
.isThrownBy(() -> Exceptions.throwIfJvmFatal(fatal1))
`
187
``
`-
.isSameAs(fatal1);
`
``
297
`+
.isThrownBy(() -> Exceptions.throwIfJvmFatal(JVM_FATAL_VIRTUAL_MACHINE_ERROR))
`
``
298
`+
.isSameAs(JVM_FATAL_VIRTUAL_MACHINE_ERROR);
`
188
299
``
189
300
`assertThatExceptionOfType(ThreadDeath.class)
`
190
301
` .as("ThreadDeath")
`
191
``
`-
.isThrownBy(() -> Exceptions.throwIfJvmFatal(fatal2))
`
192
``
`-
.isSameAs(fatal2);
`
``
302
`+
.isThrownBy(() -> Exceptions.throwIfJvmFatal(JVM_FATAL_THREAD_DEATH))
`
``
303
`+
.isSameAs(JVM_FATAL_THREAD_DEATH);
`
193
304
``
194
305
`assertThatExceptionOfType(LinkageError.class)
`
195
306
` .as("LinkageError")
`
196
``
`-
.isThrownBy(() -> Exceptions.throwIfJvmFatal(fatal3))
`
197
``
`-
.isSameAs(fatal3);
`
``
307
`+
.isThrownBy(() -> Exceptions.throwIfJvmFatal(JVM_FATAL_LINKAGE_ERROR))
`
``
308
`+
.isSameAs(JVM_FATAL_LINKAGE_ERROR);
`
``
309
+
``
310
`+
assertThat(testLogger.getErrContent())
`
``
311
`+
.startsWith("[ WARN] throwIfJvmFatal detected a jvm fatal exception, which is thrown and logged below: - custom VirtualMachineError: expected to be logged")
`
``
312
`+
.contains("[ WARN] throwIfJvmFatal detected a jvm fatal exception, which is thrown and logged below: - custom ThreadDeath: expected to be logged")
`
``
313
`+
.contains("[ WARN] throwIfJvmFatal detected a jvm fatal exception, which is thrown and logged below: - custom LinkageError: expected to be logged");
`
``
314
`+
};
`
``
315
+
``
316
`+
@Test
`
``
317
`+
@TestLoggerExtension.Redirect
`
``
318
`+
void throwIfJvmFatalDoesntThrowNorLogsOnSimplyFatalExceptions(TestLogger testLogger) {
`
``
319
`+
SoftAssertions.assertSoftly(softly -> {
`
``
320
`+
softly.assertThatCode(() -> Exceptions.throwIfJvmFatal(new BubblingException("not thrown")))
`
``
321
`+
.doesNotThrowAnyException();
`
``
322
+
``
323
`+
softly.assertThatCode(() -> Exceptions.throwIfJvmFatal(new ErrorCallbackNotImplemented(new RuntimeException("not thrown"))))
`
``
324
`+
.doesNotThrowAnyException();
`
``
325
`+
});
`
``
326
+
``
327
`+
assertThat(testLogger.getErrContent()).isEmpty();
`
198
328
` }
`
199
329
``
200
330
`@Test
`