fix(channel/feishu): register all IM event handlers to prevent HandlerNotFoundException (#196)

The Lark SDK throws HandlerNotFoundException for any event type without
a registered handler. This exception is caught internally by the SDK's
WebSocket client, which then sends a 500 response to the Feishu server.
The server may close the connection as a result, and the exception is
swallowed — never reaching the application layer.

Added empty handlers for all remaining IM event types:
- P2MessageReadV1 (read receipts)
- P2MessageRecalledV1 (message recall)
- P2ChatMemberBotDeletedV1 (bot removed from chat)
- P2ChatMemberUserAddedV1 / UserDeletedV1 / UserWithdrawnV1
- P2ChatUpdatedV1 (chat info update)
- P2ChatDisbandedV1 (chat disbanded)
- P2ChatAccessEventBotP2pChatEnteredV1 (bot entered p2p chat)

Also added explicit logback config for com.lark.oapi at WARN level
to ensure SDK internal errors are not silently filtered.

Refs: larksuite/oapi-sdk-java#185
This commit is contained in:
倪程伟 2026-05-22 16:10:05 +08:00 committed by GitHub
parent 26bf75fd2f
commit 6bf64449bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 2 deletions

View File

@ -377,7 +377,11 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
}
}
})
// Silently ignore message reaction events to avoid HandlerNotFoundException
// Silently ignore all other IM events to avoid HandlerNotFoundException.
// When the SDK receives an event without a registered handler, it throws
// HandlerNotFoundException SDK catches it and sends a 500 response
// the Feishu server may close the WebSocket connection. The exception is
// swallowed inside the SDK so it never appears in application logs.
.onP2MessageReactionCreatedV1(new ImService.P2MessageReactionCreatedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2MessageReactionCreatedV1 event) {}
@ -386,11 +390,46 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2MessageReactionDeletedV1 event) {}
})
// Silently ignore bot added to chat event to avoid HandlerNotFoundException (#153)
.onP2MessageReadV1(new ImService.P2MessageReadV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2MessageReadV1 event) {}
})
.onP2MessageRecalledV1(new ImService.P2MessageRecalledV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2MessageRecalledV1 event) {}
})
.onP2ChatMemberBotAddedV1(new ImService.P2ChatMemberBotAddedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatMemberBotAddedV1 event) {}
})
.onP2ChatMemberBotDeletedV1(new ImService.P2ChatMemberBotDeletedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatMemberBotDeletedV1 event) {}
})
.onP2ChatMemberUserAddedV1(new ImService.P2ChatMemberUserAddedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatMemberUserAddedV1 event) {}
})
.onP2ChatMemberUserDeletedV1(new ImService.P2ChatMemberUserDeletedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatMemberUserDeletedV1 event) {}
})
.onP2ChatMemberUserWithdrawnV1(new ImService.P2ChatMemberUserWithdrawnV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatMemberUserWithdrawnV1 event) {}
})
.onP2ChatUpdatedV1(new ImService.P2ChatUpdatedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatUpdatedV1 event) {}
})
.onP2ChatDisbandedV1(new ImService.P2ChatDisbandedV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatDisbandedV1 event) {}
})
.onP2ChatAccessEventBotP2pChatEnteredV1(new ImService.P2ChatAccessEventBotP2pChatEnteredV1Handler() {
@Override
public void handle(com.lark.oapi.service.im.v1.model.P2ChatAccessEventBotP2pChatEnteredV1 event) {}
})
// Interactive card button clicks (Schema 2.0) routed through cardDispatcher.
// The returned P2CardActionTriggerResponse is how Schema-2.0
// cards update in-place; PATCH /im/v1/messages/{id} is a

View File

@ -114,6 +114,9 @@
<logger name="com.zaxxer.hikari" level="INFO"/>
<logger name="io.netty" level="WARN"/>
<!-- 飞书 SDK确保事件处理异常不被过滤SDK 内部 HandlerNotFoundException 等) -->
<logger name="com.lark.oapi" level="WARN"/>
<!-- ======================== Root ======================== -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>