mirror of
https://github.com/2006-Scape/Parabot.git
synced 2026-07-02 16:49:10 +00:00
[FEATURE] Added exception handlers
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package org.parabot.environment.handlers.exceptions;
|
||||
|
||||
/**
|
||||
* Class to be implemented that allows multiple types of exception handlers
|
||||
*/
|
||||
public abstract class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
/**
|
||||
* The name of the exception handler
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The status of the exception handler; Defines if the exception handler is enabled or disabled
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* The type the handler is meant for
|
||||
*/
|
||||
private ExceptionType exceptionType;
|
||||
|
||||
public ExceptionHandler(String name, ExceptionType exceptionType) {
|
||||
this.name = name;
|
||||
this.exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
this.handle(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the exception to class extending this abstract class
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public abstract void handle(Throwable e);
|
||||
|
||||
/**
|
||||
* Returns if the exception handler is enabled or disabled
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled status of the exception handler
|
||||
*
|
||||
* @param enabled
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ExceptionHandler setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExceptionType getExceptionType() {
|
||||
return exceptionType;
|
||||
}
|
||||
|
||||
public ExceptionHandler setExceptionType(ExceptionType exceptionType) {
|
||||
this.exceptionType = exceptionType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public enum ExceptionType {
|
||||
SERVER("Server"),
|
||||
SCRIPT("Script"),
|
||||
CLIENT("Client");
|
||||
|
||||
private String name;
|
||||
|
||||
ExceptionType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.parabot.environment.handlers.exceptions;
|
||||
|
||||
import org.parabot.core.Directories;
|
||||
import org.parabot.core.ui.utils.UILog;
|
||||
import org.parabot.environment.api.utils.FileUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Writes exceptions to a file and reports the file location back to the user
|
||||
*/
|
||||
public class FileExceptionHandler extends ExceptionHandler {
|
||||
/**
|
||||
* Directory where the reports get written to
|
||||
*/
|
||||
private final File reportsDirectory;
|
||||
|
||||
/**
|
||||
* Defines if the alert should popup during this client instance again
|
||||
*/
|
||||
private boolean ignored = false;
|
||||
|
||||
/**
|
||||
* Initializes the exception handler and ensures the reports directory is created and writable
|
||||
*/
|
||||
public FileExceptionHandler(ExceptionType exceptionType) {
|
||||
super("File exception handler", exceptionType);
|
||||
|
||||
this.reportsDirectory = new File(Directories.getWorkspace(), "reports");
|
||||
if (!this.reportsDirectory.exists() || !this.reportsDirectory.isDirectory()) {
|
||||
this.reportsDirectory.mkdir();
|
||||
}
|
||||
|
||||
this.cleanOldErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Throwable e) {
|
||||
File report = new File(this.reportsDirectory, "report-" + (System.currentTimeMillis() / 1000) + ".txt");
|
||||
try {
|
||||
report.createNewFile();
|
||||
|
||||
StringBuilder reportContent = new StringBuilder();
|
||||
reportContent.append(e.getMessage() + "\n\n");
|
||||
|
||||
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
|
||||
reportContent.append(stackTraceElement);
|
||||
}
|
||||
|
||||
FileUtil.writeFileContents(report, reportContent.toString());
|
||||
|
||||
if (!ignored) {
|
||||
displayAlert(report);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIgnored() {
|
||||
return ignored;
|
||||
}
|
||||
|
||||
public FileExceptionHandler setIgnored(boolean ignored) {
|
||||
this.ignored = ignored;
|
||||
return this;
|
||||
}
|
||||
|
||||
public File getReportsDirectory() {
|
||||
return reportsDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the dialog of the alert
|
||||
*
|
||||
* @param report
|
||||
*/
|
||||
private void displayAlert(File report) {
|
||||
int response = UILog.alert(
|
||||
"Error occurred",
|
||||
"We are sorry to inform you that an error occurred within Parabot.\n\n" +
|
||||
"The error has been written to a report file.\n" +
|
||||
"Please report the error to the Parabot staff with as much information as possible.",
|
||||
new Object[]{
|
||||
"Close",
|
||||
"Open report",
|
||||
"Ignore " + this.getExceptionType().getName().toLowerCase() + " errors" },
|
||||
1,
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
);
|
||||
|
||||
switch (response) {
|
||||
case 1:
|
||||
try {
|
||||
Desktop.getDesktop().open(report);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ignored = true;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove errors older than 24 hours
|
||||
*/
|
||||
private void cleanOldErrors() {
|
||||
File[] reports = this.reportsDirectory.listFiles();
|
||||
if (reports != null) {
|
||||
for (File report : reports) {
|
||||
if (report.isFile()) {
|
||||
if ((System.currentTimeMillis() - report.lastModified()) / 1000 > 60 * 60 * 24) {
|
||||
report.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package org.parabot.environment.servers.executers;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.ui.BotUI;
|
||||
import org.parabot.core.ui.components.PaintComponent;
|
||||
import org.parabot.environment.handlers.exceptions.ExceptionHandler;
|
||||
import org.parabot.environment.handlers.exceptions.FileExceptionHandler;
|
||||
import org.parabot.environment.servers.ServerProvider;
|
||||
|
||||
/**
|
||||
@@ -15,7 +17,7 @@ public abstract class ServerExecuter {
|
||||
public abstract void run();
|
||||
|
||||
public void finalize(final ServerProvider provider, final String serverName) {
|
||||
new Thread(new Runnable() {
|
||||
Thread serverThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -30,7 +32,11 @@ public abstract class ServerExecuter {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
serverThread.setUncaughtExceptionHandler(new FileExceptionHandler(ExceptionHandler.ExceptionType.SERVER));
|
||||
|
||||
serverThread.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user