Improves error handling (foreground still needs testing).
This commit is contained in:
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user