fix(connector-slack): no construct-time Slack auth (green main)#152
Conversation
… makes no network call
Bolt's App constructor fires a construct-time auth.test() call to
api.slack.com. With fake tokens (xoxb-test / xapp-test) in tests this
resolves to an `invalid_auth` rejection — unhandled, because nothing
awaits it — causing vitest to report 3 unhandled promise rejections and
fail the process even though all 7 test assertions passed.
Fix: pass `deferInitialization: true` to the Bolt App constructor so the
auth.test() call is skipped at construction time. SlackAdapter.start()
now calls `await this.app.init()` before `await this.app.start()` to run
the deferred initialization at the right moment (Bolt 4.x API).
A new guard test ("SlackAdapter construction") constructs an adapter with
fake tokens, flushes microtasks via `await Promise.resolve()`, and asserts
no throw/rejection — locks in the network-free construction invariant.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughSlackAdapter's Bolt App construction now sets deferInitialization: true, and start() explicitly calls app.init() before app.start() to complete deferred initialization. A new test verifies constructing SlackAdapter does not throw synchronously or trigger an immediate unhandled rejection. ChangesSlack Adapter deferred init
Estimated code review effort: 1 (Trivial) | ~5 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant SlackAdapter
participant BoltApp
Caller->>SlackAdapter: new SlackAdapter(tokens)
SlackAdapter->>BoltApp: new App({ deferInitialization: true })
Note over BoltApp: no auth.test() call yet
Caller->>SlackAdapter: start()
SlackAdapter->>BoltApp: await app.init()
SlackAdapter->>BoltApp: await app.start()
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Root cause
SlackAdapter's constructor callednew App({ token, appToken, socketMode: true }).Bolt's
Appconstructor fires a construct-timeauth.test()call toapi.slack.comtofetch bot identity. In tests, fake tokens (
xoxb-test/xapp-test) make this rejectwith
invalid_auth. Nothing awaited the rejection, so vitest reported 3 unhandled promiserejections and failed the process — even though all 7 assertions passed.
Fix
Production fix (preferred over
vi.mock):deferInitialization: truedeferInitialization: trueto the BoltAppconstructor options. This is anofficial Bolt 4.x API that skips the construct-time
auth.test()call entirely.SlackAdapter.start()now callsawait this.app.init()beforeawait this.app.start()to run the deferred initialization at the correct moment (Bolt's
init()→start()sequence when
deferInitializationis used).No mock or test-only shim is needed — the fix is in production code, which also benefits
real integrations where you want to construct the adapter before credentials are verified
(e.g. DI containers, lazy initialization).
New guard test
Added a
'SlackAdapter construction'describe block that:SlackAdapterwith fake tokens and asserts no synchronous throw.await Promise.resolve()to surface any immediate rejection.This test locks in the network-free construction invariant so regressions are caught immediately.
Verification
🤖 Generated with Claude Code
Summary by CodeRabbit