Is there a best practice to be followed when writing many try-except blocks?

A simple example to show what I mean, assume that I have 3 .py files (file1, file2, file3) which perform different tasks for me, and I need to log errors at every step, is this the correct way of going about it or is there another best practice that can be followed?

file1.py:

def some_function(some_var):
    try:
        if some_var == 0:
            raise ValueError("Can't be zero")
        else:
            return 1
    except ValueError:
        raise

file2.py

import file1

def some_other_fn(some_other_var):
    try:
        return file1.some_function(some_other_var)
    except:
        raise

file3.py

import file2
import traceback

try:
    res = f2.some_other_fn(0)
except:
    # handle err
    print(traceback.format_exc())

Of course, another question, as I am re-raising the many types of errors I can encounter in file1, (lets say 4+), should I be catch the same 4 errors across different files? This seems to be redundant code. Is there a way for me to know in file3 what kind of error occurred in file1 without explicitly writing an except ValueError in both file2 and file3?

Please note that exiting in file1 and file2 is not possible, file3 is the main control flow and other functions must return to it.

Answer

You don’t seem to understand how try-except works. Please repeat your tutorials for examples. Since the base code does not have the potential to raise a run-time error, the try-except construct is inappropriate. It’s silly to manually cause an exception, wrap that in a try-except block, merely to re-raise that same exception.

Instead:

def some_function(some_var):
    if some_var == 0:
        raise ValueError("Can't be zero")
    else:
        return 1

Similarly, your next function has a functionally null try-except block. You don’t specifically handle the exception in any way, so all you’ve done is to replicate the default exception propagation — the run-time system already does this.

Instead:

import file1

def some_other_fn(some_other_var):
    return file1.some_function(some_other_var)

In your final block, you finally use try-except correctly:

  1. You execute code that might throw an exception;
  2. if it does, then you react to the exception.