Improves error handling (foreground still needs testing).

This commit is contained in:
Markil3
2021-09-14 11:21:02 -06:00
parent 3eab100a08
commit 849771853c
11 changed files with 623 additions and 181 deletions

View File

@@ -0,0 +1,44 @@
package edu.regis.universeplayer.browserCommands;
/**
* A debugging command that instructs the browser to throw an error.
*/
public class CommandError implements BrowserCommand
{
private boolean forward;
/**
* Creates an error command.
*
* @param forward - Determines where the error should be thrown. If true, it
* will be thrown from the website tab. If false, it will be
* thrown by the addon background script.
*/
public CommandError(boolean forward)
{
this.forward = forward;
}
/**
* Checks whether the error will be thrown from the foreground or background
* script.
*
* @return True if the error will be thrown from the foreground script,
* false if it will be thrown from the background.
*/
public boolean isForeground()
{
return this.forward;
}
/**
* Obtains the name of the command.
*
* @return The command name.
*/
@Override
public String getCommandName()
{
return "error";
}
}

View File

@@ -21,17 +21,17 @@ import java.util.concurrent.Future;
public class MessageHandler implements Runnable, MessageSerializer
{
private final Logger logger;
public final String name;
private final InputStream input;
private final OutputStream output;
private final ExecutorService executor;
private final LinkedList<MessageListener> listeners = new LinkedList<>();
protected final HashMap<Integer, Future<Object>> messageResponses = new HashMap<>();
protected final Queue<Object> updates = new LinkedList<>();
/**
* Creates a message handler.
*
@@ -47,13 +47,13 @@ public class MessageHandler implements Runnable, MessageSerializer
this.output = output;
this.executor = Executors.newCachedThreadPool();
}
@Override
public Logger getLogger()
{
return logger;
}
/**
* Called at the beginning of every loop to do extra processing and check to see if we can still run.
*
@@ -63,13 +63,13 @@ public class MessageHandler implements Runnable, MessageSerializer
{
return false;
}
@Override
public void run()
{
BufferedInputStream browserIn = null;
BufferedOutputStream browserOut = null;
byte[][] message;
byte[] messageByte;
Object messageOb;
@@ -77,12 +77,12 @@ public class MessageHandler implements Runnable, MessageSerializer
ByteBuffer numBuffer = ByteBuffer.allocate(4);
HashSet<Integer> toRemove = new HashSet<>();
boolean running = true;
try
{
browserIn = new BufferedInputStream(this.input);
browserOut = new BufferedOutputStream(this.output);
while (!this.onRun() && running)
{
try
@@ -99,22 +99,32 @@ public class MessageHandler implements Runnable, MessageSerializer
{
numBuffer.clear();
numBuffer.put(message[0]);
messageOb = this.deserializeObject(message[1]);
messageResponse = this.triggerListeners(messageOb);
try
{
messageOb = this.deserializeObject(message[1]);
}
catch (IOException | ClassNotFoundException e)
{
logger.error("Could not read message", e);
messageOb = this.getErrorObject(e);
}
messageResponse = this
.triggerListeners(messageOb);
synchronized (this.messageResponses)
{
numBuffer.clear();
this.messageResponses.put(numBuffer.getInt(), messageResponse);
this.messageResponses.put(numBuffer
.getInt(), messageResponse);
}
}
}
}
catch (IOException | ClassNotFoundException e)
catch (IOException e)
{
logger.error("Could not retrieve message", e);
running = false;
}
/*
* Returns any finished responses.
*/
@@ -143,7 +153,7 @@ public class MessageHandler implements Runnable, MessageSerializer
toRemove.clear();
}
}
/*
* Send in any updates
*/
@@ -218,14 +228,14 @@ public class MessageHandler implements Runnable, MessageSerializer
}
}
}
/**
* Callback for when closing the application.
*/
protected void onClose()
{
}
/**
* Triggers the message listeners.
*
@@ -254,7 +264,7 @@ public class MessageHandler implements Runnable, MessageSerializer
});
return returnVal;
}
/**
* Adds a message listener
*
@@ -268,7 +278,7 @@ public class MessageHandler implements Runnable, MessageSerializer
this.listeners.add(listener);
}
}
/**
* Sends an object through the handler as an update not associated with any message.
*
@@ -281,7 +291,7 @@ public class MessageHandler implements Runnable, MessageSerializer
this.updates.add(object);
}
}
/**
* Checks to see if a listener has been added to the list.
*
@@ -295,7 +305,7 @@ public class MessageHandler implements Runnable, MessageSerializer
return this.listeners.contains(listener);
}
}
/**
* Removes a message listener from the list.
*
@@ -308,7 +318,7 @@ public class MessageHandler implements Runnable, MessageSerializer
this.listeners.remove(listener);
}
}
/**
* A message listener is called when a message is sent from the remote.
*

View File

@@ -12,7 +12,7 @@ import java.nio.ByteBuffer;
public interface MessageSerializer
{
Logger getLogger();
/**
* Converts an object into a form that can be sent.
*
@@ -31,13 +31,14 @@ public interface MessageSerializer
return byteStream.toByteArray();
}
}
/**
* Converts a byte stream into an object.
*
* @param message - The message received.
* @return An object.
* @throws IOException If there is an error in parsing the message.
* @throws IOException If there is an error in parsing the
* message.
* @throws ClassNotFoundException If the object is not recognized
*/
default Object deserializeObject(byte[] message) throws IOException, ClassNotFoundException
@@ -50,12 +51,13 @@ public interface MessageSerializer
}
}
}
/**
* Writes a message to the output stream.
*
* @param out - The output stream to write to.
* @param messageNum - The ID of the message being sent. This will help keep track of responses.
* @param messageNum - The ID of the message being sent. This will help keep
* track of responses.
* @param message - The actual message contents to write.
* @throws IOException Thrown when an exception occures
*/
@@ -86,7 +88,7 @@ public interface MessageSerializer
out.write(message);
out.flush();
}
/**
* Reads a message from the input stream
*
@@ -119,7 +121,8 @@ public interface MessageSerializer
readLength = in.read(lengthBuffer.array());
if (readLength == 0)
{
getLogger().error("Malformed message, could not get message length.");
getLogger()
.error("Malformed message, could not get message length.");
return null;
}
message = new byte[lengthBuffer.getInt()];
@@ -129,9 +132,21 @@ public interface MessageSerializer
readLength = in.read(message);
if (readLength < message.length)
{
getLogger().warn("Message shorter than reported (expected {} bytes, got {} bytes)", message.length, readLength);
getLogger()
.warn("Message shorter than reported (expected {} bytes, got {} bytes)", message.length, readLength);
}
getLogger().trace("Reading message");
return new byte[][] {messageNum, message};
return new byte[][]{messageNum, message};
}
/**
* This method is called when an error in deserialization occurs.
*
* @param e - The error thrown.
* @return An object to return to listeners in the event of a read error.
*/
default Object getErrorObject(Throwable e)
{
return e;
}
}