I don't think there was really anything wrong with your prior approach. It seems like the advice you got was to make the Er type more generic, which may or may not be appropriate in the context of your application. At this point, Er is now a monad transformer. It's not really a monad until the "m" type parameter is instantiated. For example:
type ErActuallyAMonad a = Er Error a
Notice that the value inside the newtype will then be a "StateT ErState Error a", which is almost the same as the "ErrorT (State ErState) a" you had originally.
An instance declaration like this is saying that if you have a MonadError monad m, and you transform it with the transformer Er, then the resulting monad will also be a MonadError monad. These instance declarations are pretty common in the MTL.
-Karl