Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FunctionTimedOut can't be catch by expcet Exception as e: . #29

Open
yougrianes opened this issue Feb 15, 2023 · 4 comments
Open

FunctionTimedOut can't be catch by expcet Exception as e: . #29

yougrianes opened this issue Feb 15, 2023 · 4 comments

Comments

@yougrianes
Copy link

I find that FunctionTimedOut is the same level exceptions as Exception, and both create from BaseException. this thing makes me a little bit confused at the first time.

@secsilm
Copy link

secsilm commented May 12, 2023

Agree. I have to use except BaseException as e to catch the error. Really confused. What's the design purpose?

@caic99
Copy link

caic99 commented Sep 15, 2023

Raising an exception from BaseException rather than Exception makes multiprocessing.map failed to handle the exceptions in subprocess, causing the process pool failed to join.

import os
import multiprocessing
from multiprocessing import Pool
import func_timeout
from func_timeout import func_set_timeout

@func_set_timeout(1)
def dummy(x):
    os.system("sleep 1")
    return x

def wrapper(x):
    try:
        return dummy(x)
    except Exception as e:
        # func_timeout.exceptions.FunctionTimedOut
        # raise
        print(e)
        return None

logger = multiprocessing.log_to_stderr()
logger.setLevel(multiprocessing.SUBDEBUG)

with Pool(8) as pool:
    r = pool.map(wrapper, range(100), chunksize=8)
print(r)

@brianquirion
Copy link

I think it should definitely inherits from Exception rather than BaseException. It causes issues on our side because we want to just catch Exception error and not catch BaseException errors like a systemexit or keyboardinterrupt. So we need to wrap calls to this libs just to rethrow a normal error that inherits from Exception instead of BaseException. A bit convoluted imo.

@Moeinoddin-Mansourfar
Copy link

Moeinoddin-Mansourfar commented Jul 3, 2024

same issue today, an exception handler i configured in FastApi wouldn't handle such timeout errors

# Exception handler for general exceptions
@app.exception_handler(Exception)
async def generic_exception_handler(request, exc: Exception):    
    return await _error_formatter(error_message=str(exc),
                                  error_type="server_error",
                                  status_code=500,
                                  )

@app.get("/some_long_job")
async def some_long_job(arg1, arg2):
    result = func_timeout.func_timeout(timeout=0.02, func=some_specific_long_job, args=(arg1, arg2))
    return result

went to source code of "FunctionTimedOut" and changed baseException to Exception, obviously a bad idea.

this is my current workaroud:

class TimeoutException(Exception):
    pass

def func_timeout_handleable(timeout: float,
                            func: any,
                            args: tuple = (),
                            kwargs: dict = None,
                            specific_error_message: str = None
                            ):
    try:
        result = func_timeout.func_timeout(timeout=timeout, func=func, args=args, kwargs=kwargs)
        return result
    except func_timeout.exceptions.FunctionTimedOut:
        if specific_error_message is None:
            raise TimeoutException(f"timed out after {timeout} seconds")
        else:
            raise TimeoutException(specific_error_message)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants