Clean up error handling

Cleans up the error handling so that it is run at demux level rather than dispatcher level. This allows us to also add error handling around the outer loop just in case some goes wrong with the queue.
Also removed the old way of assigning the error handler, moving more to a strategy pattern using classes such as the DefaultErrorHandler rather than passing methods. It can also take lambdas.