Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pkg/channels/wecom/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,12 @@ func NewWeComAppChannel(cfg config.WeComAppConfig, messageBus *bus.MessageBus) (
channels.WithReasoningChannelID(cfg.ReasoningChannelID),
)

ctx, cancel := context.WithCancel(context.Background())
return &WeComAppChannel{
BaseChannel: base,
config: cfg,
ctx: ctx,
cancel: cancel,
processedMsgs: make(map[string]bool),
}, nil
}
Expand Down Expand Up @@ -567,8 +570,9 @@ func (c *WeComAppChannel) handleMessageCallback(ctx context.Context, w http.Resp
return
}

// Process the message with context
go c.processMessage(ctx, msg)
// Process the message with the channel's long-lived context (not the HTTP
// request context, which is canceled as soon as we return the response).
go c.processMessage(c.ctx, msg)
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c.ctx may be nil here if the channel hasn't been started yet (e.g., current tests invoke handleMessageCallback on a newly constructed channel without calling Start). A nil context will panic downstream in BaseChannel.HandleMessage / MessageBus.PublishInbound when ctx.Err() is called. Ensure c.ctx is always non-nil (initialize it in NewWeComAppChannel, or add a safe fallback here when c.ctx == nil).

Suggested change
go c.processMessage(c.ctx, msg)
procCtx := c.ctx
if procCtx == nil {
procCtx = context.Background()
}
go c.processMessage(procCtx, msg)

Copilot uses AI. Check for mistakes.
Comment on lines +573 to +575
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current webhook callback tests only check the immediate HTTP response and don't assert that the async goroutine successfully publishes the inbound message. Add a regression test that cancels the request context and verifies an inbound message is still consumed from the bus (e.g., ConsumeInbound with a timeout), so this bugfix stays covered.

Copilot uses AI. Check for mistakes.

// Return success response immediately
// WeCom App requires response within configured timeout (default 5 seconds)
Expand Down
8 changes: 6 additions & 2 deletions pkg/channels/wecom/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,12 @@ func NewWeComBotChannel(cfg config.WeComConfig, messageBus *bus.MessageBus) (*We
channels.WithReasoningChannelID(cfg.ReasoningChannelID),
)

ctx, cancel := context.WithCancel(context.Background())
return &WeComBotChannel{
BaseChannel: base,
config: cfg,
ctx: ctx,
cancel: cancel,
processedMsgs: make(map[string]bool),
}, nil
}
Expand Down Expand Up @@ -292,8 +295,9 @@ func (c *WeComBotChannel) handleMessageCallback(ctx context.Context, w http.Resp
return
}

// Process the message asynchronously with context
go c.processMessage(ctx, msg)
// Process the message with the channel's long-lived context (not the HTTP
// request context, which is canceled as soon as we return the response).
go c.processMessage(c.ctx, msg)
Comment on lines +298 to +300
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are existing tests for handleMessageCallback, but they only assert the HTTP response and don't validate the async processing path. Please add a regression test that passes a canceled request context into handleMessageCallback and asserts an inbound message is still published (e.g., via msgBus.ConsumeInbound with a timeout), to prevent reintroducing the "context canceled" failure this change is addressing.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c.ctx can be nil here when the channel hasn't been started yet (e.g., current unit tests call handleMessageCallback without calling Start). Passing a nil context into processMessage eventually reaches BaseChannel.HandleMessageMessageBus.PublishInbound(ctx, ...), which will panic on ctx.Err(). Initialize a non-nil default (e.g., set c.ctx = context.Background() in the constructor, or fall back to context.Background()/a detached context here when c.ctx == nil).

Suggested change
go c.processMessage(c.ctx, msg)
procCtx := c.ctx
if procCtx == nil {
procCtx = context.Background()
}
go c.processMessage(procCtx, msg)

Copilot uses AI. Check for mistakes.

// Return success response immediately
// WeCom Bot requires response within configured timeout (default 5 seconds)
Expand Down