I'm writing a small Python program and need to choose a Desktop directory. Right now I'm checking whether `Path.home() / "Desktop"` exists, and otherwise falling back to `Path.home() / "OneDrive" / "Desktop"`:
```python
if (Path.home() / "Desktop").exists():
desktop_path = Path.home() / "Desktop"
else:
desktop_path = Path.home() / "OneDrive" / "Desktop"
```
This made me wonder about the general rule: when should a situation be handled with normal `if`/`else` logic, and when is `try`/`except` more appropriate? Is either approach preferable for this path-selection example?
4 Answers
Creating a `Path` object does not access the filesystem and normally cannot fail, so there is nothing useful to catch around the path construction itself. A simple version would avoid calling `Path.home()` repeatedly:
```python
home = Path.home()
local_desktop = home / "Desktop"
one_drive_desktop = home / "OneDrive" / "Desktop"
desktop_path = local_desktop if local_desktop.is_dir() else one_drive_desktop
```
If neither directory is guaranteed to exist, check both and decide what to do when no candidate works—for example, raise `FileNotFoundError`, create a directory if appropriate, or ask the user for a location.
There may be a more reliable platform-specific way to locate the user's Desktop than guessing between two folder names. On Windows, a known-folder API can provide the configured Desktop location, which also handles cases where it has been redirected or renamed. If portability and correctness matter, use that mechanism or let the user choose a directory instead of assuming it is on the Desktop.
Use `if`/`else` when you're making a decision based on a condition you can check normally. Use `try`/`except` when an operation may raise an exception and you have a meaningful way to recover from it. In this example, checking whether a path exists is ordinary conditional logic, so `if`/`else` is reasonable. However, checking first and using the path later can have a time-of-check/time-of-use race: the directory could disappear or become inaccessible after the check. The operation that actually uses the directory should still handle relevant exceptions.
Don't use exceptions as a replacement for ordinary branching. They are best for failures during an operation, such as opening a file, connecting to a database, or writing data. Catch only exceptions you can actually handle, and catch them close to the operation that may fail. A missing file can be expected in one context and fatal in another, so whether it belongs in `try`/`except` depends on what the caller can recover from.
Exactly—`FileNotFoundError` isn't automatically an exceptional situation. Trying to open an optional settings file is different from trying to open a file that the program just created and requires.

That distinction matters more in threaded or distributed programs, where the state can change between the check and the operation.