If you aren't aware of it, note that custom service already collect information about exceptions and return it in a special failure contract. Consider simply using the standard solution before building something custom.
If your catch clause doesn't catch error exceptions, a common reason is that your code is inside a DB transaction. Look at ttslevel in debugger; you'll likely find that the operation is indeed wrapped in a transaction.
If you want to know the type of the exception, look at the type of the object inside $exception value in debugger, or the variable you use when catching System.Exception.
Regarding your numbered questions:
1. There isn't an universal answer. For example, if you want to access properties of CLR exceptions and not just infolog messages, the plain catch wouldn't work for you.
2. Both catch all exceptions.
3. You already seem to know how to do it, therefore repeating it would be a waste of time for both of us.
4. Yes.