import asyncio
from typing import Any, Callable
from pydantic import ValidationError

class ServiceException(Exception):
    error_code: str
    msg: str

    def __init__(self, msg: str, method_name: str, error_code: str = 'UnknownSessionError'):
        self.error_code = error_code
        message = f"[ServiceException] {error_code} in {method_name} - {msg}"
        self.msg = message 
        super().__init__(message)

def exception_handler(func: Callable[..., Any]) -> Callable[..., Any]:
    if asyncio.iscoroutinefunction(func):
        async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
            try:
                return await func(*args, **kwargs)
            except FileNotFoundError as e:
                raise ServiceException(f"A file not found error occurred: {e}", func.__name__, "FileNotFound")
            except ValidationError as e:
                raise ServiceException(f"A validation error occurred: {e}", func.__name__, "ValidationError")
            except ValueError as e:
                raise ServiceException(f"An value error occurred: {e}", func.__name__, "ValueError")
            except Exception as e:
                raise ServiceException(f"An unexpected error occurred: {e}", func.__name__, "UnexpectedError")
        return async_wrapper
    else:
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            try:
                return func(*args, **kwargs)
            except FileNotFoundError as e:
                raise ServiceException(f"A file not found error occurred: {e}", func.__name__, "FileNotFound")
            except ValidationError as e:
                raise ServiceException(f"A validation error occurred: {e}", func.__name__, "ValidationError")
            except ValueError as e:
                raise ServiceException(f"An value error occurred: {e}", func.__name__, "ValueError")
            except Exception as e:
                raise ServiceException(f"An unexpected error occurred: {e}", func.__name__, "UnexpectedError")
        return wrapper
