How to handle errors and messages without raising exception? (pythonic way)

62 views Asked by At

I have a program which has a lot of functions inside. And all this functions calls another functions. This functions has try catch blocks for to handle errors. I have to handle this errors without raising errors, because i am trying to do api application, i am loosing the control of handling errors.

So i wrote following code block, how can i solve this problem in a pythonic way?

def second_funct(param1):
   _return = True
   _error_message = ""
    try:
       print("second_funct")
       #some processing
       print(1/0)
    except Exception as e:
       _return = False
       _error_message = e
    return _return, _error_message

def third_funct(param2):
    _return = True
    _error_message = ""
    try:
        print("third_funct")
        #some processing
    except Exception as e:
        _return = False
        _error_message = e
    return _return, _error_message

def main():
    _return = True
    _error_message = ""
    _param1 = 0
    _param2 = 0
    try:
        print("main_funct")
        #some processing
        _return, _error_message = second_funct(_param1)
        if(_return):
            print("go third_funct")
            _return, _error_message = third_funct(_param2)
            if(_return):
                #some process
                print("ok")
            else:
                print(_error_message)
        else:
            print(_error_message)
    except Exception as e:
        print(e)

main()

Result of this code ;

main_funct
second_funct
division by zero
1

There are 1 answers

1
Christoph On

Here a example what you can do, when using a decorator, this would use an Error handling like in golang, because u should always handle Errors.

from functools import wraps

def catch_errors(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
            return result, None
        except Exception as e:
            return None, str(e)
    return wrapper

@catch_errors
def second_funct(param1):
    print("second_funct")
    print(1/0)  # This will cause a division by zero error, demonstrating error handling.

@catch_errors
def third_funct(param2):
    print("third_funct")

def main():
    print("main_funct")
    _param1 = 0
    _param2 = 0
    
    result, err = second_funct(_param1)
    if err:
        print(err)
        return

    print("go third_funct")
    result, err = third_funct(_param2)
    if err:
        print(err)
        return

    print("ok")

main()

Update, a Version using a diffrent approche without an decorator.

from dataclasses import dataclass, field
from typing import Any, Callable, Optional, Tuple, Dict

@dataclass
class Result:
    value: Any = None
    error: Optional[str] = None

@dataclass
class FunctionCall:
    func: Callable
    args: Tuple[Any, ...] = field(default_factory=tuple)
    kwargs: Dict[str, Any] = field(default_factory=dict)
    
    def execute(self) -> Result:
        try:
            value = self.func(*self.args, **self.kwargs)
            return Result(value=value)
        except Exception as e:
            return Result(error=str(e))

def second_funct(param1):
    print("second_funct")
    # This will cause a division by zero error, demonstrating error handling
    return 1/0

def third_funct(param2):
    print("third_funct")
    # This function simulates successful execution
    return "Success"

def main():
    print("main_funct")
    function_calls = [
        FunctionCall(func=second_funct, args=(0,)),
        FunctionCall(func=third_funct, args=(0,))
    ]
    
    for call in function_calls:
        result = call.execute()
        if result.error:
            print(result.error)
            return
    
    print("ok")

main()