Alex Rivera | Logout

To fault or not to fault

Asked 2010-12-14T15:45:57.100
10

I'm having a discussion with a colleague about when to throw faults and when not to throw faults in a WCF service.

One opinion is, that we only throw faults when the service operation could not do its work due to some error; and something may be in an invalid state because of it. So, some examples:

  • ValidateMember(string name, string password, string country) -> would throw a fault if the mandatory parameters are not passed, because the validation itself could not be executed; -> would throw fault if some internal error occured, like database was down -> would return a status contract in all other cases, that specifies the result of the validation (MemberValidated, WrongPassword, MemberNotKnown,...)

  • GetMember(int memberId) -> would only throw fault if something is down, in all other cases it would return the member or null if not found

The other opinion is that we should also throw faults when GetMember does not find the member, or in the case of ValidateMember the password is wrong.

What do you think?

Edit
Report

1 Answer

12

My take on this...

There are three causes of failure:

  1. The service code threw an exception, e.g. database error, logic error in your code. This is your fault.
  2. The client code failed to use your service properly according to your documentation, e.g. it didn't set a required flag value, it failed to pass in an ID. This is the client software developer's fault.
  3. The end user typed in something silly on screen, e.g. missing date of birth, negative salary. This is the end user's fault.

It's up to you how you choose to map actual fault contracts to each cause of failure. For example, we do this:

  • For causes 1 and 2, all the client code needs to know is that the service failed. We define a very simple "fatal error" fault contract that contains only a unique error ID. The full details of the error are logged on the server.
  • For cause 3, the end user needs to know exactly what he/she did wrong. We define a "validation errors" fault contract containing a collection of friendly error messages for the client code to display on screen.

We borrow the Microsoft EntLib class for cause 3, and use exception shielding to handle causes 1 and 2 declaratively. It makes for very simple code.

To Clarify:

We handle the three causes like this inside the service:

  1. An unexpected exception is thrown in the service code. We catch it at the top level (actually exception shielding catches it, but the principle is the same). Log full details, then throw a FaultException<ServiceFault> to the client containing only the error ID.
  2. We validate the input data
answered 2010-12-14T16:59:51.557

Your Answer