ExceptionUtil.java

1
package com.jsql.util;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.util.bruter.HashUtil;
5
import org.apache.commons.lang3.exception.ExceptionUtils;
6
import org.apache.logging.log4j.Level;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9
10
import javax.swing.*;
11
import java.lang.reflect.InvocationTargetException;
12
import java.nio.charset.StandardCharsets;
13
import java.security.MessageDigest;
14
import java.security.NoSuchAlgorithmException;
15
import java.util.Set;
16
import java.util.concurrent.CopyOnWriteArraySet;
17
18
/**
19
 * Utility class managing exception reporting to GitHub.
20
 */
21
public class ExceptionUtil {
22
    
23
    private static final Logger LOGGER = LogManager.getRootLogger();
24
    
25
    private final InjectionModel injectionModel;
26
    
27
    private final Set<String> exceptionsMd5Cached = new CopyOnWriteArraySet<>();
28
    
29
    public ExceptionUtil(InjectionModel injectionModel) {
30
        
31
        this.injectionModel = injectionModel;
32
    }
33
    
34
    /**
35
     * Handler class processing errors on top of the JVM in order to send
36
     * a report to GitHub automatically.
37
     */
38
    public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
39
40
        @Override
41
        public void uncaughtException(Thread thread, Throwable throwable) {
42
            
43
            LOGGER.log(
44
                LogLevelUtil.CONSOLE_JAVA,
45 1 1. lambda$uncaughtException$0 : replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$0 → NO_COVERAGE
                () -> String.format("Unhandled Exception on %s", thread.getName()),
46
                throwable
47
            );
48
49
            // Display to stdout
50
            LOGGER.log(
51
                Level.ERROR,
52 1 1. lambda$uncaughtException$1 : replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$1 → NO_COVERAGE
                () -> String.format("Unhandled Exception on %s", thread.getName()),
53
                throwable
54
            );
55
56
            // Report #214: ignore if OutOfMemoryError: Java heap space
57
            if (
58 1 1. uncaughtException : negated conditional → NO_COVERAGE
                ExceptionUtil.this.injectionModel.getMediatorUtils().getPreferencesUtil().isReportingBugs()
59 2 1. uncaughtException : negated conditional → NO_COVERAGE
2. uncaughtException : negated conditional → NO_COVERAGE
                && ExceptionUtils.getStackTrace(throwable).contains("com.jsql")
60
                && !(throwable instanceof OutOfMemoryError)
61 1 1. uncaughtException : negated conditional → NO_COVERAGE
                && !ExceptionUtils.getStackTrace(throwable).contains("OutOfMemoryError")  // when implicit
62
            ) {
63
64 1 1. uncaughtException : negated conditional → NO_COVERAGE
                if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class java.awt.Toolkit")) {
65
66
                    LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing, please use a proper Java runtime instead of headless runtime");
67
                    return;
68
69 1 1. uncaughtException : negated conditional → NO_COVERAGE
                } else if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class sun.awt.X11.XToolkit")) {
70
71
                    LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing or wrong DISPLAY variable, please verify your settings");
72
                    return;
73
                }
74
75
                try {
76
                    var md = MessageDigest.getInstance("Md5");
77
78
                    String stackTrace = ExceptionUtils.getStackTrace(throwable).trim();
79
                    var passwordString = String.valueOf(stackTrace.toCharArray());
80
81
                    byte[] passwordByte = passwordString.getBytes(StandardCharsets.UTF_8);
82 1 1. uncaughtException : removed call to java/security/MessageDigest::update → NO_COVERAGE
                    md.update(passwordByte, 0, passwordByte.length);
83
84
                    byte[] encodedPassword = md.digest();
85
86
                    var md5Exception = HashUtil.digestToHexString(encodedPassword);
87
88 1 1. uncaughtException : negated conditional → NO_COVERAGE
                    if (!ExceptionUtil.this.exceptionsMd5Cached.contains(md5Exception)) {
89
90
                        ExceptionUtil.this.exceptionsMd5Cached.add(md5Exception);
91 1 1. uncaughtException : removed call to com/jsql/util/GitUtil::sendUnhandledException → NO_COVERAGE
                        ExceptionUtil.this.injectionModel.getMediatorUtils().getGitUtil().sendUnhandledException(
92
                            thread.getName(),
93
                            throwable
94
                        );
95
                    }
96
                } catch (NoSuchAlgorithmException e) {
97
                    LOGGER.log(LogLevelUtil.IGNORE, e);
98
                }
99
            }
100
        }
101
    }
102
    
103
    /**
104
     * Add the error reporting mechanism on top of the JVM in order to
105
     * intercept and process the error to GitHub.
106
     */
107
    public void setUncaughtExceptionHandler() {
108
        
109
        // Regular Exception
110 1 1. setUncaughtExceptionHandler : removed call to java/lang/Thread::setDefaultUncaughtExceptionHandler → NO_COVERAGE
        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
111
112
        // Event dispatching thread Exception
113
        try {
114 1 1. setUncaughtExceptionHandler : removed call to javax/swing/SwingUtilities::invokeAndWait → NO_COVERAGE
            SwingUtilities.invokeAndWait(() ->
115
                // We are in the event dispatching thread
116 1 1. lambda$setUncaughtExceptionHandler$0 : removed call to java/lang/Thread::setUncaughtExceptionHandler → NO_COVERAGE
                Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler())
117
            );
118
        } catch (InvocationTargetException | InterruptedException e) {
119
            
120
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
121 1 1. setUncaughtExceptionHandler : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
122
        }
123
    }
124
}

Mutations

45

1.1
Location : lambda$uncaughtException$0
Killed by : none
replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$0 → NO_COVERAGE

52

1.1
Location : lambda$uncaughtException$1
Killed by : none
replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$1 → NO_COVERAGE

58

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

59

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

61

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

64

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

69

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

82

1.1
Location : uncaughtException
Killed by : none
removed call to java/security/MessageDigest::update → NO_COVERAGE

88

1.1
Location : uncaughtException
Killed by : none
negated conditional → NO_COVERAGE

91

1.1
Location : uncaughtException
Killed by : none
removed call to com/jsql/util/GitUtil::sendUnhandledException → NO_COVERAGE

110

1.1
Location : setUncaughtExceptionHandler
Killed by : none
removed call to java/lang/Thread::setDefaultUncaughtExceptionHandler → NO_COVERAGE

114

1.1
Location : setUncaughtExceptionHandler
Killed by : none
removed call to javax/swing/SwingUtilities::invokeAndWait → NO_COVERAGE

116

1.1
Location : lambda$setUncaughtExceptionHandler$0
Killed by : none
removed call to java/lang/Thread::setUncaughtExceptionHandler → NO_COVERAGE

121

1.1
Location : setUncaughtExceptionHandler
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1