Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To fault or not to fault

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?

like image 978
L-Four Avatar asked Dec 14 '10 15:12

L-Four


People also ask

What does to no-fault of my own mean?

From Longman Dictionary of Contemporary Englishthrough no fault of her/my etc ownthrough no fault of her/my etc own used to say that something bad that happened to someone was not caused by them Through no fault of our own we are currently two players short.

What is the full meaning of fault?

Definition of fault 1a : weakness, failing especially : a moral weakness less serious than a vice He loves her despite her many faults. b : a physical or intellectual imperfection or impairment : defect a theory with some serious faults.

Who was at fault meaning?

Responsible for a mistake, trouble, or failure; deserving blame. For example, At least three cars were involved in the accident, so it was hard to determine which driver was at fault, or He kept missing the target and wondered if the sight on his new rifle was at fault.

Does not fault meaning?

DEFINITIONS1. with no regard for who is to blame for an event or situation. No-fault divorces and no-fault car insurance are examples where blame is not an important factor. Synonyms and related words. Miscellaneous legal terms.


3 Answers

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 and deliberately throw an exception. It's normally an ArgumentException, but any appropriate type would do. Once it is thrown, it is dealt with in exactly the same way as (1) because we want to make it appear the same to the client.
  3. We validate the input data and deliberately throw an exception. This time, it's a FaultException<ValidationFault>. We configure exception shielding to pass this one through un-wrapped, so it appears on the client as FaultException<ValidationFault> not FaultException<ServiceFault>.

End result:

  • No catch blocks at all inside the service (nice clean code).
  • Client only has to catch FaultException<ValidationFault> if it wants to display messages to the user. All other exception types including FaultException<ServiceFault> are dealt with by the client's global error handler as fatal errors, since a fatal error in the service generally means a fatal error in the client as well.
like image 156
Christian Hayter Avatar answered Oct 24 '22 15:10

Christian Hayter


It it is a common, routine failure, then throwing a fault is a mistake. The software should be written to handle routine items, like entering the wrong password. Fault processing is for exceptional failure which are not considered part of the program's normal design.

For example, if your program was written with the idea that it always has access to a database, and the database is not accessible, that's an issue where the "fix" is well outside of the limits of your software. A fault should be thrown.

Fault processing uses different logical flows through the structure of the programming language, and by using it only when you've "left" the normal processing of the programming problem, you will make your solution leverage the feature of the programming language in a way that seems more natural.

like image 32
Edwin Buck Avatar answered Oct 24 '22 16:10

Edwin Buck


I believe it is good practice to separate error handling and fault handling. Any error case should be dealt by your program - fault handling is reserved for exceptional conditions. As a guide to the separation of the two I found it useful when considering such cases to remember that there are only three types of error (when handling data and messages) and only one type of fault. The error types are related to different types of validation:

  1. Message validation - you can determine from the message contents that the data is valid or invalid.

    Example: content that is intended to be a date of birth - you can tell from the data whether it is valid or not.

  2. Context validation - you can only determine that content is invalid by reference to the message combined with the system state.

    Example: a valid date of joining a company is earlier than that persons date of birth.

  3. Lies to the system - you can only determine that a message was in error when a later message throws up an anomaly.

    Example: Valid date of birth stored and inspection of the person's birth certificate shows this to be incorrect. Correction of lies to the system generally require action outside of the system, for instance invoking legal or disciplinary remedies.

Your system MUST deal with all classes of error - though in case three this may be limited to issuing an alert.

Faults (exceptions) by contrast only have one cause - data corruption (which includes data truncation). Example: validation parameters are not passed.

Here the appropriate mechanism is fault or exception handling - basically handing off the problem to some other part of the system that is capable of dealing with it (which is why there should be an ultimate destination for unhandled faults).

like image 22
Chris Walton Avatar answered Oct 24 '22 17:10

Chris Walton