Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

We\'re discussing the best way to handle errors in calls to a method. We have a

ID: 642202 • Letter: W

Question

We're discussing the best way to handle errors in calls to a method.

We have a credit model where we allow users to deduct credits for certain actions. We'd like to make a call to:

User.DeductCredits(10);
Then the Deduct method will check things like

Does the user exist?
Is the user active?
Does the user have at least 10 credits?
If not, this result should fail.

We're currently writing this just as a class library, but trying to keep it open to convert to a web service in the future. The options we've discussed so far are:

Throw an exception when an error occurs.
Create a new Result object that would have T has the type of data expected back, and wrapping that with a status code and message.
We didn't like option #1, because then code to call deduct credits would look something like:

try
{
   user.DeductCredits(10);
}
catch(InvalidUserException e)
{
}
catch(InactiveUserException e)
{
}
catch(CreditBalanceException e)
{
}
Additionally, if we turn this in to a service, we can't force exceptions on the user.

The main reason we didn't like option #2 was that it seemed to be returning more data than what we need. For example:

var address = user.GetMailAddress();
Now address has the status code and message, as well as a data property, or value property. So to get the city, you'd have code like:

if(!address.HasError)
   state = address.Data.State;
as opposed to:

state = address.State;
So is there a best practice for this type of situation? Is one option really any better than the other?

Explanation / Answer

The best practice is a combination of the two: if it is a real error, (something that should not really happen,) then you should throw an exception. If it is not a real error, but something that may happen within the regular course of things, then the function should return some sort of a result enum. In your case, without knowing the specifics and just guessing from the names I see, it seems to me that "invalid user" is an error, so an exception should be thrown, while "inactive user" and "insufficient funds" are probably not errors, but results.

I assume that by "user" you mean the programmer who will be using your service. In my book, "we can't force exceptions on the user" is just plain dead wrong. You must force exceptions on the user; as a matter of fact, the user expects exceptions when things go wrong. That's the way things are done in this millennium. Also, do not worry, you will very rarely, if ever, need to write multiple catch statements for all possible exceptions. Try it, and you will see that in actual usage scenarios things do not work that way.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote