Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not use exceptions as regular flow of control?

People also ask

Why is it bad to use exceptions for control flow?

The use of exceptions for program flow control hides the programmer's intention, that is why it is considered a bad practice. It is hard to reason about ProcessItem function because you can't say what the possible results are just by looking at its signature.

Why should exceptions not be used as an alternate form of program control?

Exceptions should rarely be used because exceptional situations are rare and exceptions are expensive. Rare, because you don't expect your program crash at every button press or at every malformed user input.

Can we write exceptions in usual flow of program?

Answer: Exceptions are events that disrupt the normal flow of the program. We can handle exceptions in our program and continue with the program normally. An error is an irrecoverable event that cannot be handled and terminates the program.

When should exceptions not be used?

Don't use exceptions to signal something completely normal. Don't use exceptions to control your normal application flow. Use return values or state fields for flow control instead.


Have you ever tried to debug a program raising five exceptions per second in the normal course of operation ?

I have.

The program was quite complex (it was a distributed calculation server), and a slight modification at one side of the program could easily break something in a totally different place.

I wish I could just have launched the program and wait for exceptions to occur, but there were around 200 exceptions during the start-up in the normal course of operations

My point : if you use exceptions for normal situations, how do you locate unusual (ie exceptional) situations ?

Of course, there are other strong reasons not to use exceptions too much, especially performance-wise


Exceptions are basically non-local goto statements with all the consequences of the latter. Using exceptions for flow control violates a principle of least astonishment, make programs hard to read (remember that programs are written for programmers first).

Moreover, this is not what compiler vendors expect. They expect exceptions to be thrown rarely, and they usually let the throw code be quite inefficient. Throwing exceptions is one of the most expensive operations in .NET.

However, some languages (notably Python) use exceptions as flow-control constructs. For example, iterators raise a StopIteration exception if there are no further items. Even standard language constructs (such as for) rely on this.


My rule of thumb is:

  • If you can do anything to recover from an error, catch exceptions
  • If the error is a very common one (eg. user tried to log in with the wrong password), use returnvalues
  • If you can't do anything to recover from an error, leave it uncaught (Or catch it in your main-catcher to do some semi-graceful shutdown of the application)

The problem I see with exceptions is from a purely syntax point of view (I'm pretty sure the perfomance overhead is minimal). I don't like try-blocks all over the place.

Take this example:

try
{
   DoSomeMethod();  //Can throw Exception1
   DoSomeOtherMethod();  //Can throw Exception1 and Exception2
}
catch(Exception1)
{
   //Okay something messed up, but is it SomeMethod or SomeOtherMethod?
}

.. Another example could be when you need to assign something to a handle using a factory, and that factory could throw an exception:

Class1 myInstance;
try
{
   myInstance = Class1Factory.Build();
}
catch(SomeException)
{
   // Couldn't instantiate class, do something else..
}
myInstance.BestMethodEver();   // Will throw a compile-time error, saying that myInstance is uninitalized, which it potentially is.. :(

Soo, personally, I think you should keep exceptions for rare error-conditions (out of memory etc.) and use returnvalues (valueclasses, structs or enums) to do your error checking instead.

Hope I understood your question correct :)


A first reaction to a lot of answers :

you're writing for the programmers and the principle of least astonishment

Of course! But an if just isnot more clear all the time.

It shouldn't be astonishing eg : divide (1/x) catch (divisionByZero) is more clear than any if to me (at Conrad and others) . The fact this kind of programming isn't expected is purely conventional, and indeed, still relevant. Maybe in my example an if would be clearer.

But DivisionByZero and FileNotFound for that matter are clearer than ifs.

Of course if it's less performant and needed a zillion time per sec, you should of course avoid it, but still i haven't read any good reason to avoid the overal design.

As far as the principle of least astonishment goes : there's a danger of circular reasoning here : suppose a whole community uses a bad design, this design will become expected! Therefore the principle cannot be a grail and should be concidered carefully.

exceptions for normal situations, how do you locate unusual (ie exceptional) situations ?

In many reactions sth. like this shines trough. Just catch them, no? Your method should be clear, well documented, and hounouring it's contract. I don't get that question I must admit.

Debugging on all exceptions : the same, that's just done sometimes because the design not to use exceptions is common. My question was : why is it common in the first place?