# Straight-line code: Correct usage of exceptions:

Using exceptions correctly depends on distinguishing control flow from errors.
Function naming and function prototype shaping is perhaps the best way to ensure
that these are separated properly.

If these naming and prototype design conventions are followed, then a program
ought to be able to written without checking the results of operations; and the
programmer should be able to trust that exceptions will handle violations of xis
assumptions out of band.

## Find vs Get:

findFoo(): Looks for Foo and returns a data type which is expected both to
	tolerate and communicate emptiness.
	E.g: std::optional, std::shared/unique_ptr.
	* Does not throw if Foo is not found because caller's expectations are
	  tentative.
```
std::optional<Foo> SomeManager::findFoo(std::string searchCriteria)
{
	for (item: collection)
	{
		if (item.property != searchCriteria) { continue; }
		return item;
	}
}
```

getFoo/retrieveFoo(): Looks for foo and throws if foo isn't found because caller
	expects foo exist, and non-existence is a program error. Conceptually is a
	wrapper around findFoo() that throws if !findFoo(). In practice due to
	locking requirements it may often be necessary to implement getFoo() with
	its own function body and not reuse findFoo().
	* Returns references or smart pointers, or similar types.
```
Foo &SomeManager::getFoo(std::string searchCriteria)
{
	auto ret = findFoo(searchCriteria);
	if (!ret) { throw("Foo not found with criteria " +searchCriteria); }
	return ret.get();
}
```

## 