David Mason
David Mason

Reputation: 329

When to throw Exception

Although I read a lot about Exception Handling, I am still not sure when to throw one and when not.

For example I have an API as three tier architecture and in the DB layer events can occur.

In the first case I am not throwing an exception, because nothing really "goes wrong". My repository function just returns "null" to tell upper layers that nothing was found. But the other two cases are already tricky.

It does not make sense to me if a deleteById-function returns "null" if the id was not found. I could return "false" if the deletion was not successful and "true" if it was successful. But then I have to transport this from database layer, through domain layer to the presentation layer. Throwing an Exception would just be easy to me. But in this case I also did not produce "unexpected behaviour". Like in the first case, nothing "goest wrong". Isnt there any kind of "best pracice"?

What would you do?

Upvotes: 3

Views: 1619

Answers (3)

Max94
Max94

Reputation: 125

you have to throw an exception when something unexpected goes wrong. with your example =>

  1. a getById call return item | null if not found => there is no error if does not exist

  2. the repo.Delete function MUST have a valid id => db function throw an exception(better if ArgumentException )... BUT the controller/manager need to catch(ArgumentException) and then 2 options:

    2a. 'delete not exist item' => success -> after method call, item does not exist

    2b. es: controller send error message to client 'Item you're want to delete does not exist'

  3. repo.Update function must have valid id => like above without 2a option

if function NEED this param => throw

if function manage 'not found=null' case => not throw

Upvotes: 0

Zohar Peled
Zohar Peled

Reputation: 82474

I argue that you shouldn't throw an exception in any of these cases - here's why:
Exceptions should be used for exceptional things - mainly things you can't control in code - such as a network connection error and stuff like that.
Throwing exceptions for non-exceptional situations is just, well, vexing, as Eric Lipprt explains so much better than I can.

  • Try to receive a customer from database, but customer with the given id was not found.

Well, that's a no brainer - You didn't find a customer in the database - return null. No reason to throw an exception because there's nothing exceptional in this situation.

  • Try to delete a customer by id, but the id was not found in database.

If the customer was found in the database, then this operation would result with the removal of this customer.
If it wasn't found in the database - the end result is still the same as if it was found - so why should you care it wasn't there in the first place? Again, no reason to throw an exception.

  • Try to update a customer by id, but the id was not found in database.

This one is the most tricky to explain, but there are basically two legitimate ways to handle this situation:

One way is to do what any database does when an update statement has a where clause that doesn't fit any row in the table - and that's simply do nothing.
As far as letting the client know if there was an actual update or it was a no-op, you can check the number of rows effected and return true/false or customer/null to the client.

The other way, is to convert the update to an "upserts" - so if the customer is not found on the database, simply create a new customer.
This can also be indicated back to the client using a simple true/false return value. In that case, you should name the method properly - AddOrUpdateCustomer, for instance.

Upvotes: 4

andresantacruz
andresantacruz

Reputation: 1724

You should not use exceptions as a way to signal caller for expected execution flows. This should be done returning a meaningful value as the function returns. If your function return is more complex and couldn't be expressed by simple true/false returns, you can declare an enum to use as return value or even a Tuple in more complex scenarios.

Try to receive a customer from database, but customer with the given id was not found.

Try to delete a customer by id, but the id was not found in database.

Try to update a customer by id, but the id was not found in database.

All this 3 possible situations should be well handled by DB and when such a path happens, just return a value to the caller with enough information so it can handle the result and act properly.

Upvotes: 1

Related Questions