Skip to content

Commit ecdfb53

Browse files
authored
Fix slackapi#87 by correcting App internals (slackapi#88)
* Fix slackapi#87 by correcting App internals * Remove unnecessary changes * Make an error message in tests consistent * Fix the issues detected by pytype
1 parent 6355714 commit ecdfb53

7 files changed

Lines changed: 59 additions & 23 deletions

File tree

slack_bolt/app/app.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,20 @@ def run_ack_function_asynchronously():
323323
except Exception as e:
324324
# The default response status code is 500 in this case.
325325
# You can customize this by passing your own error handler.
326-
if response is None:
327-
response = BoltResponse(status=500)
328-
response.status = 500
329-
if ack.response is not None: # already acknowledged
330-
response = None
331-
332-
self._listener_error_handler.handle(
333-
error=e, request=request, response=response,
334-
)
335-
ack.response = response
326+
if listener.auto_acknowledgement:
327+
self._listener_error_handler.handle(
328+
error=e, request=request, response=response,
329+
)
330+
else:
331+
if response is None:
332+
response = BoltResponse(status=500)
333+
response.status = 500
334+
if ack.response is not None: # already acknowledged
335+
response = None
336+
self._listener_error_handler.handle(
337+
error=e, request=request, response=response,
338+
)
339+
ack.response = response
336340

337341
self._listener_executor.submit(run_ack_function_asynchronously)
338342

@@ -768,12 +772,12 @@ def __init__(
768772
self._port: int = port
769773
self._bolt_endpoint_path: str = path
770774
self._bolt_app: App = app
771-
self._bolt_oauth_flow: OAuthFlow = oauth_flow
775+
self._bolt_oauth_flow: Optional[OAuthFlow] = oauth_flow
772776

773777
_port: int = self._port
774778
_bolt_endpoint_path: str = self._bolt_endpoint_path
775779
_bolt_app: App = self._bolt_app
776-
_bolt_oauth_flow: OAuthFlow = self._bolt_oauth_flow
780+
_bolt_oauth_flow: Optional[OAuthFlow] = self._bolt_oauth_flow
777781

778782
class SlackAppHandler(SimpleHTTPRequestHandler):
779783
def do_GET(self):

slack_bolt/middleware/authorization/async_multi_teams_authorization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async def async_process(
7373
# TODO: bot -> user token
7474
req.context["token"] = bot.bot_token
7575
req.context["client"] = create_async_web_client(bot.bot_token)
76-
return next()
76+
return await next()
7777

7878
except SlackApiError as e:
7979
self.logger.error(f"Failed to authorize with the given token ({e})")

slack_bolt/middleware/authorization/multi_teams_authorization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from slack_bolt.response import BoltResponse
77
from slack_sdk.errors import SlackApiError
88
from slack_sdk.oauth.installation_store import InstallationStore, Bot
9-
from . import Authorization
9+
from .authorization import Authorization
1010
from .internals import _build_error_response, _is_no_auth_required
1111
from ...util.utils import create_web_client
1212

slack_bolt/middleware/authorization/single_team_authorization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Callable, Optional
22

33
from slack_bolt.logger import get_bolt_logger
4-
from slack_bolt.middleware.authorization import Authorization
4+
from .authorization import Authorization
55
from slack_bolt.request import BoltRequest
66
from slack_bolt.response import BoltResponse
77
from slack_sdk.errors import SlackApiError

slack_bolt/oauth/async_oauth_flow.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
AsyncFailureArgs,
1212
)
1313
from slack_bolt.oauth.async_oauth_settings import AsyncOAuthSettings
14-
from slack_bolt.request import BoltRequest
14+
from slack_bolt.request.async_request import AsyncBoltRequest
1515
from slack_bolt.response import BoltResponse
1616
from slack_sdk.errors import SlackApiError
1717
from slack_sdk.oauth import OAuthStateUtils
@@ -140,18 +140,18 @@ def sqlite3(
140140
# Installation
141141
# -----------------------------
142142

143-
async def handle_installation(self, request: BoltRequest) -> BoltResponse:
143+
async def handle_installation(self, request: AsyncBoltRequest) -> BoltResponse:
144144
state = await self.issue_new_state(request)
145145
return await self.build_authorize_url_redirection(request, state)
146146

147147
# ----------------------
148148
# Internal methods for Installation
149149

150-
async def issue_new_state(self, request: BoltRequest) -> str:
150+
async def issue_new_state(self, request: AsyncBoltRequest) -> str:
151151
return await self.settings.state_store.async_issue()
152152

153153
async def build_authorize_url_redirection(
154-
self, request: BoltRequest, state: str
154+
self, request: AsyncBoltRequest, state: str
155155
) -> BoltResponse:
156156
return BoltResponse(
157157
status=302,
@@ -167,22 +167,22 @@ async def build_authorize_url_redirection(
167167
# Callback
168168
# -----------------------------
169169

170-
async def handle_callback(self, request: BoltRequest) -> BoltResponse:
170+
async def handle_callback(self, request: AsyncBoltRequest) -> BoltResponse:
171171

172172
# failure due to end-user's cancellation or invalid redirection to slack.com
173173
error = request.query.get("error", [None])[0]
174174
if error is not None:
175175
return await self.failure_handler(
176176
AsyncFailureArgs(
177177
request=request,
178-
reason=error,
178+
reason=error, # type: ignore
179179
suggested_status_code=200,
180180
settings=self.settings,
181181
)
182182
)
183183

184184
# state parameter verification
185-
state = request.query.get("state", [None])[0]
185+
state: Optional[str] = request.query.get("state", [None])[0]
186186
if not self.settings.state_utils.is_valid_browser(state, request.headers):
187187
return await self.failure_handler(
188188
AsyncFailureArgs(
@@ -302,7 +302,7 @@ async def run_installation(self, code: str) -> Optional[Installation]:
302302
return None
303303

304304
async def store_installation(
305-
self, request: BoltRequest, installation: Installation
305+
self, request: AsyncBoltRequest, installation: Installation
306306
):
307307
# may raise BoltError
308308
await self.settings.installation_store.async_save(installation)

tests/scenario_tests/test_events.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,21 @@ def handle_app_mention(body, say, payload, event):
143143
assert self.mock_received_requests["/auth.test"] == 1
144144
sleep(1) # wait a bit after auto ack()
145145
assert self.mock_received_requests["/chat.postMessage"] == 1
146+
147+
def test_stable_auto_ack(self):
148+
app = App(client=self.web_client, signing_secret=self.signing_secret)
149+
150+
@app.event("reaction_added")
151+
def handle_app_mention():
152+
raise Exception("Something wrong!")
153+
154+
for _ in range(10):
155+
timestamp, body = (
156+
str(int(time())),
157+
json.dumps(self.valid_reaction_added_body),
158+
)
159+
request: BoltRequest = BoltRequest(
160+
body=body, headers=self.build_headers(timestamp, body)
161+
)
162+
response = app.dispatch(request)
163+
assert response.status == 200

tests/scenario_tests_async/test_events.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ async def test_reaction_added(self):
129129
await asyncio.sleep(1) # wait a bit after auto ack()
130130
assert self.mock_received_requests["/chat.postMessage"] == 1
131131

132+
@pytest.mark.asyncio
133+
async def test_stable_auto_ack(self):
134+
app = AsyncApp(client=self.web_client, signing_secret=self.signing_secret,)
135+
app.event("reaction_added")(always_failing)
136+
137+
for _ in range(10):
138+
request = self.build_valid_reaction_added_request()
139+
response = await app.async_dispatch(request)
140+
assert response.status == 200
141+
132142

133143
app_mention_body = {
134144
"token": "verification_token",
@@ -189,3 +199,7 @@ async def whats_up(body, say, payload, event):
189199
async def skip_middleware(req, resp, next):
190200
# return next()
191201
pass
202+
203+
204+
async def always_failing():
205+
raise Exception("Something wrong!")

0 commit comments

Comments
 (0)