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

Make Exeption traceable in lazy listener #635

Open
3 tasks
jimmymaise opened this issue Apr 20, 2022 · 5 comments
Open
3 tasks

Make Exeption traceable in lazy listener #635

jimmymaise opened this issue Apr 20, 2022 · 5 comments
Assignees
Labels
Milestone

Comments

@jimmymaise
Copy link

(Describe your issue and goal here)
Currently, using lazy listener for FAAS (such as AWS Lambda), it's really difficult to debug. If we have a exception, we just have something like

Failed to run an internal function (Exception ABC)

We don't know exactly, what is the error, traceback, error line etc...

 try:
            await internal_func(
                **build_async_required_kwargs(
                    logger=logger,
                    required_arg_names=arg_names,
                    request=request,
                    response=None,
                    this_func=internal_func,
                )
            )
        except Exception as e:
            logger.error(f"Failed to run an internal function ({e})")

So should we have an option to enable the exception traceback or provide some meaningful error information to debug instead of just simply message like that

On the other hand, the document about error handling does not work with lazy listener so we also need to update.
https://slack.dev/bolt-python/concepts#errors

Category (place an x in each of the [ ])

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components
  • Adapters in slack_bolt.adapter
  • [x ] Others

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

@jimmymaise jimmymaise changed the title Make Exeption traceable in lazy listion Make Exeption traceable in lazy listener Apr 20, 2022
@seratch seratch added this to the 1.x milestone Apr 20, 2022
@seratch seratch self-assigned this Apr 20, 2022
@seratch
Copy link
Member

seratch commented Apr 20, 2022

Hi @jimmymaise, thanks for the feedback. We will look into this. This can be improved in future versions and/or needs to be clearly mentioned in the documents.

@ddhanak
Copy link

ddhanak commented Aug 18, 2022

We are facing the same issue as @jimmymaise, I think it would be helpful to have the exception traceback (we are using sentry and would love to see what line is causing the issue).

@kevgliss
Copy link

We are also facing this issue; it's often unclear what is causing an exception (or swallowing them entirely).

@angrychimp
Copy link
Contributor

I'm running into this issue frequently as well. I'd love to see this updated

@os1ma
Copy link

os1ma commented Apr 20, 2024

I'm running into the same issue.

As a workaround, I was able to display the stack trace with the following code.

from concurrent.futures import Executor
from functools import wraps
from logging import Logger
from typing import Callable

from slack_bolt.kwargs_injection import build_required_kwargs
from slack_bolt.lazy_listener.runner import LazyListenerRunner
from slack_bolt.request import BoltRequest
from slack_bolt.util.utils import get_arg_names_of_callable


def build_runnable_function(
    func: Callable[..., None],
    logger: Logger,
    request: BoltRequest,
) -> Callable[[], None]:
    arg_names = get_arg_names_of_callable(func)

    @wraps(func)
    def request_wired_func_wrapper() -> None:
        try:
            func(
                **build_required_kwargs(
                    logger=logger,
                    required_arg_names=arg_names,
                    request=request,
                    response=None,
                    this_func=func,
                )
            )
        except Exception as e:
-            logger.error(f"Failed to run an internal function ({e})")
+            logger.exception(f"Failed to run an internal function ({e})")

    return request_wired_func_wrapper


class PatchedThreadLazyListenerRunner(LazyListenerRunner):
    logger: Logger

    def __init__(
        self,
        logger: Logger,
        executor: Executor,
    ):
        self.logger = logger
        self.executor = executor

    def start(self, function: Callable[..., None], request: BoltRequest) -> None:
        self.executor.submit(
            build_runnable_function(
                func=function,
                logger=self.logger,
                request=request,
            )
        )
app.listener_runner.lazy_listener_runner = PatchedThreadLazyListenerRunner(
    logger=app._framework_logger,
    executor=app.listener_runner.listener_executor,
)

However, this is a hacky workaround that strongly depends on the internal structure of this framework, so it's not desirable. I would be happy if bolt framework would resolve this issue.

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

No branches or pull requests

6 participants