1 | package fr.sii.ogham.core.util; | |
2 | ||
3 | import java.util.function.Predicate; | |
4 | import java.util.regex.Pattern; | |
5 | ||
6 | import org.slf4j.Logger; | |
7 | import org.slf4j.LoggerFactory; | |
8 | ||
9 | /** | |
10 | * Utility class for exceptions | |
11 | * | |
12 | * @author Aurélien Baudet | |
13 | * | |
14 | */ | |
15 | public final class ExceptionUtils { | |
16 | private static final Logger LOG = LoggerFactory.getLogger(ExceptionUtils.class); | |
17 | private static final Pattern INDENT = Pattern.compile("^", Pattern.MULTILINE); | |
18 | ||
19 | /** | |
20 | * Predicate that returns {@code true} if any cause in the exception stack | |
21 | * matches the cause predicate. | |
22 | * | |
23 | * <p> | |
24 | * If a cause matches the predicate, then it return {@code true} immediately | |
25 | * (skipping other checks). | |
26 | * | |
27 | * @param error | |
28 | * the root error to analyze | |
29 | * @param causePredicate | |
30 | * the predicate to apply to causes recursively | |
31 | * @return true if the cause predicate returns true for at least one cause | |
32 | * in the exception stack | |
33 | */ | |
34 | public static boolean hasAnyCause(Throwable error, Predicate<Throwable> causePredicate) { | |
35 | Throwable cause = error; | |
36 |
4
1. hasAnyCause : negated conditional → NO_COVERAGE 2. hasAnyCause : negated conditional → KILLED 3. hasAnyCause : negated conditional → KILLED 4. hasAnyCause : negated conditional → KILLED |
while (cause != null) { |
37 |
4
1. hasAnyCause : negated conditional → NO_COVERAGE 2. hasAnyCause : negated conditional → SURVIVED 3. hasAnyCause : negated conditional → KILLED 4. hasAnyCause : negated conditional → KILLED |
if (causePredicate.test(cause)) { |
38 |
4
1. hasAnyCause : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → NO_COVERAGE 2. hasAnyCause : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → KILLED 3. hasAnyCause : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → KILLED 4. hasAnyCause : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → KILLED |
return true; |
39 | } | |
40 | cause = cause.getCause(); | |
41 | } | |
42 |
4
1. hasAnyCause : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → NO_COVERAGE 2. hasAnyCause : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → SURVIVED 3. hasAnyCause : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → KILLED 4. hasAnyCause : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::hasAnyCause → KILLED |
return false; |
43 | } | |
44 | ||
45 | /** | |
46 | * Checks whether the error has been raised due to a Java {@link Error}. | |
47 | * {@link Error}s should not be ignored. For example, if there is a | |
48 | * {@link OutOfMemoryError}, retrying may result in consuming more memory | |
49 | * and totally crash the JVM or hang the system. | |
50 | * | |
51 | * @param error | |
52 | * the raised error | |
53 | * @return true if the error is fatal JVM error | |
54 | */ | |
55 | public static boolean fatalJvmError(Throwable error) { | |
56 |
6
1. fatalJvmError : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → SURVIVED 2. fatalJvmError : replaced boolean return with false for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → NO_COVERAGE 3. fatalJvmError : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → NO_COVERAGE 4. fatalJvmError : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → KILLED 5. fatalJvmError : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → KILLED 6. fatalJvmError : replaced boolean return with true for fr/sii/ogham/core/util/ExceptionUtils::fatalJvmError → KILLED |
return error instanceof Error; |
57 | } | |
58 | ||
59 | /** | |
60 | * Generate a String based on the exception. Unlike default | |
61 | * {@link Throwable#toString()} method, the {@link Throwable#getCause()} may | |
62 | * also be included in the generated string (depending of logging | |
63 | * configuration). If logger associated to this class is configured to | |
64 | * {@code DEBUG} or {@code TRACE}, then the cause is included. | |
65 | * | |
66 | * @param e | |
67 | * the error to convert to a string | |
68 | * @return the error string | |
69 | */ | |
70 | public static String toString(Throwable e) { | |
71 |
2
1. toString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toString → SURVIVED 2. toString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toString → NO_COVERAGE |
return toString(e, ""); |
72 | } | |
73 | ||
74 | /** | |
75 | * Generate a String based on the exception. Unlike default | |
76 | * {@link Throwable#toString()} method, the {@link Throwable#getCause()} may | |
77 | * also be included in the generated string (depending of logging | |
78 | * configuration). If logger associated to this class is configured to | |
79 | * {@code DEBUG} or {@code TRACE}, then the cause is included. | |
80 | * | |
81 | * @param e | |
82 | * the error to convert to a string | |
83 | * @param indentation | |
84 | * the initial indentation | |
85 | * @return the error string | |
86 | */ | |
87 | public static String toString(Throwable e, String indentation) { | |
88 | String str = toThrowableString(e, indentation); | |
89 | if (LOG.isDebugEnabled() || LOG.isTraceEnabled()) { | |
90 | str += toCauseString(e, indentation + " "); | |
91 | } | |
92 |
2
1. toString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toString → NO_COVERAGE 2. toString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toString → SURVIVED |
return str; |
93 | } | |
94 | ||
95 | private static String toThrowableString(Throwable e, String indentation) { | |
96 |
2
1. toThrowableString : negated conditional → SURVIVED 2. toThrowableString : negated conditional → NO_COVERAGE |
if (e == null) { |
97 | return ""; | |
98 | } | |
99 | String s = e.getClass().getName(); | |
100 | String message = e.getLocalizedMessage(); | |
101 |
4
1. toThrowableString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toThrowableString → SURVIVED 2. toThrowableString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toThrowableString → NO_COVERAGE 3. toThrowableString : negated conditional → NO_COVERAGE 4. toThrowableString : negated conditional → SURVIVED |
return indent(indentation, (message != null) ? (s + ": " + message) : s); |
102 | } | |
103 | ||
104 | private static String toCauseString(Throwable e, String indentation) { | |
105 |
2
1. toCauseString : negated conditional → SURVIVED 2. toCauseString : negated conditional → NO_COVERAGE |
if (e == null) { |
106 | return ""; | |
107 | } | |
108 | Throwable cause = e.getCause(); | |
109 |
2
1. toCauseString : negated conditional → NO_COVERAGE 2. toCauseString : negated conditional → SURVIVED |
if (cause == null) { |
110 | return ""; | |
111 | } | |
112 |
2
1. toCauseString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toCauseString → SURVIVED 2. toCauseString : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::toCauseString → NO_COVERAGE |
return "\n" + indent(indentation, toString(cause, indentation)); |
113 | } | |
114 | ||
115 | private static String indent(String indentation, String str) { | |
116 |
2
1. indent : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::indent → NO_COVERAGE 2. indent : replaced return value with "" for fr/sii/ogham/core/util/ExceptionUtils::indent → SURVIVED |
return INDENT.matcher(str).replaceAll(indentation); |
117 | } | |
118 | ||
119 | private ExceptionUtils() { | |
120 | super(); | |
121 | } | |
122 | } | |
Mutations | ||
36 |
1.1 2.2 3.3 4.4 |
|
37 |
1.1 2.2 3.3 4.4 |
|
38 |
1.1 2.2 3.3 4.4 |
|
42 |
1.1 2.2 3.3 4.4 |
|
56 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
71 |
1.1 2.2 |
|
92 |
1.1 2.2 |
|
96 |
1.1 2.2 |
|
101 |
1.1 2.2 3.3 4.4 |
|
105 |
1.1 2.2 |
|
109 |
1.1 2.2 |
|
112 |
1.1 2.2 |
|
116 |
1.1 2.2 |