Consider:
How do you report service level messages or errors in higher layers using MVP?
I am not sure how to specifically help here. First of all, I really don’t understand your setup or I don’t know anything about WCF characteristics. Secondly, I really do not comment on exceptions for logic logic ... but I assume that you mean "business verification", as you stated elsewhere (in this case, it makes sense to me).
In my ignorance, it seems that you have the beginning of your own scheme, so perhaps you have a lot of freedom. And of course, a lot can work. So here are a few alternatives:
Communication method
You can just try your approach and see how you like it. IMO, this mix touches a little to test and work together (sometimes this may not help, especially if you start asking how to handle failures). Command-Query, on the side, is a classic throwback issue, and at that boundary you have the right to choose either as long as it works.
If you have a framework for your MVP, you can see if there is anything in it.
If you do not agree with this, you can change the PL / SL ratio to separately verify the correct operation. For instance:
IList<Error> Validate_Operation1(Entity1 a){} Entity2 Operation1(Entity1 a){}
Or to be crazy:
public interface ICommand { IList<Param> Params { set; } IList<Error> Validate(); void Execute(); }
If I firmly differentiated "Verification Errors", except for "Errors after Verification" and "Unexpected Errors", I could do the above. Getting validation issues as a result of a validation request is certainly not “exceptional”.
All that aside, you might think about getting more abstract information about what you are going to do with errors after checking. Some of them can be pushed to action, regardless of whether they are connected or not. "Datatraveler looks corrupt. Please reformat your finger pointer." Or even warnings such as "Settings not found, filled by default." If your application is very interactive, your chatty SL can use a more general mechanism to send back validation questions.
Communication Content
I don’t see your Response-class-with-error-enums-and-null objects as miles different from defining your own error or exception class, honestly. I'm not big on a “multipurpose” return like this, but there is a case for this approach: many EventArgs or asynchronous callback arguments are implemented to get error information, cancellation and results.
As for your listed flaw, I'm not sure how wide the hierarchy of errors is when you say: “PL should handle all cases defined in exceptionInfo”, so forgive me for being the worst here. The car you choose (exceptions, simple strings or the exceptionInfo enumeration) does not change the fact that if you recognize 762 different errors, you will recognize 762 different errors.
But this does not mean that your speakers should consider each of them explicitly. You have the advantage of context - you know that you will not get the "Username is empty" after the user has already logged in and checks his balance on mortgage loans. (And if you do, you should probably consider it as “Unexpected errors when checking your balance. Please try again later.” And register the call stack, right?)
Thus, your facilitator only needs to know a shorter list that is relevant to his context, and not all of them. Everything else is "Suddenly ...".
And since you are defining your own class of errors, you might consider placing your errors in string resources and binding the resource identifier to a specific error when creating the object. Then, instead of processing cases individually, many of them can be resolved with the same action: Get ID, load string, show string, done. No switch statement is required.