Alan Evangelista
Alan Evangelista

Reputation: 3163

Using exception to control code flow

afaik using exceptions to handle code flow is wrong. I'm working in a code that has a method named getEntity(id) and getEntity throws a DoesNotExist exception when entity is not found. There is no entityExists(id) method. To check if a entity exists, code usually does:

try: 
   getEntity(id)
catch DoesNotExist as e:
   # entity does not exist

It seems to me this would be better:

if not entityExists(id):
   # entity does not exist

This ^ is common sense? I think the code is like that because it uses Django and it is copying Django exception name (DoesNotExist) and its usual way of handling the inexistence of an entity.

The question is not specific to Python, but the code I'm using as example is in Python, therefore I've tagged the question with Python.

Upvotes: 2

Views: 498

Answers (2)

Max
Max

Reputation: 22365

In my opinion it depends on the context. If you know for sure of all possible outcomes, go ahead and do your if/elses (LBYL). If you are unsure of the possible outcomes (for example when dealing with a variable of an unknown type), try/catch (EAFP) is a much safer way to go.

Upvotes: 0

johnsyweb
johnsyweb

Reputation: 141860

This is known as EAFP or Easier to ask for forgiveness than permission. From The Python Glossary:

This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as .

LBYL means Look before you leap. Again from The Python Glossary:

This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.

It then goes on to give a good counter-example to your if not entityExists(id): suggestion:

In a multi-threaded environment, the LBYL approach can risk introducing a race condition between “the looking” and “the leaping”. For example, the code, if key in mapping: return mapping[key] can fail if another thread removes key from mapping after the test, but before the lookup. This issue can be solved with locks or by using the EAFP approach.

When writing in Python (or any language), it helps to follow the idioms of that language, this makes your code easier to grok by others who read it.

Upvotes: 8

Related Questions