JeffreySu/WeiXinMPSDK · error · MessageHandlerException
请使用异步方法 OnExecutingAsync()
Error message
请使用异步方法 OnExecutingAsync()
What it means
In the MP MessageHandler, the synchronous OnExecuting override is marked [Obsolete(..., true)] and unconditionally throws MessageHandlerException. The library migrated its message-processing pipeline to async (OnExecutingAsync), so calling the sync hook is a compile-time-warning but run-time hard error: the sync path is no longer supported.
Solutions
- Replace all synchronous handler invocation with the async pipeline: call MessageHandler.ExecuteAsync() (or the async request-message extension), which uses OnExecutingAsync/OnExecutedAsync.
- Move your pre-processing logic from an OnExecuting override into OnExecutingAsync override in your custom handler.
- Update old sync extension methods / framework wrappers (e.g. MessageHandler<T>.Execute sync overloads) to their Async equivalents.
- Treat compiler CS0619 (obsolete-with-error) on OnExecuting as the signal: fix call sites at compile time rather than at runtime.
Example fix
// before
messageHandler.OnExecuting();
messageHandler.Execute();
// after
await messageHandler.ExecuteAsync(cancellationToken); // pipeline calls OnExecutingAsync internally
// custom handler
public override async Task OnExecutingAsync(CancellationToken ct)
{
// pre-processing here
} Defensive patterns
Strategy: type-guard
Validate before calling
// compile-time: treat Obsolete-with-error as a build failure #pragma warning disable CS0619 // deliberately detect sync usage // do NOT reference messageHandler.OnExecuting(); #pragma warning restore CS0619
Type guard
bool UsesAsyncPipeline(MessageHandler<TRequest, TResponse> h) =>
h.GetType().GetMethod(nameof(MessageHandler<TRequest, TResponse>.OnExecutingAsync)) != null; Try / catch
try { await messageHandler.ExecuteAsync(ct); }
catch (MessageHandlerException ex) when (ex.Message.Contains("OnExecutingAsync"))
{
logger.LogError(ex, "Sync OnExecuting invoked; migrate to ExecuteAsync");
throw;
} Prevention
- Always invoke handlers through ExecuteAsync, never the sync Execute path.
- Enable 'warnings as errors' so [Obsolete(true)] misuse fails the build.
- Put pre-processing in OnExecutingAsync overrides only.
- Update old samples/wrappers when upgrading Senparc.Weixin major versions.
When it happens
Trigger: Calling messageHandler.OnExecuting() directly, overriding it in a subclass and relying on the base synchronous Execute() pipeline, or using legacy sync extension/pipeline code (e.g. old Weixin MpMessageHandler helper overloads) that invokes the sync hook.
Common situations: Migrating code written against older Senparc.Weixin versions (pre-async pipeline) to a newer version where the sync OnExecuting/OnExecuted were made throw-on-use; following outdated blog samples that call sync message handler methods inside ASP.NET (non-Core) controllers.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- 请使用异步方法 OnExecutedAsync()
- MsgType: 在RequestMessageFactory中没有对应的处理程序!
- 微信公众号不支持 IResponseMessageMpNews 响应类型
- 微信公众号不支持 IRequestMessageMiniProgramPage 响应类型
- 微信请求发生错误!错误代码: ,说明:
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/afdb29db9edf9a82.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.MP/Senparc.Weixin.MP/MessageHandlers/MessageHandler.cs:358
// return null;
// }
// var responseMessage = RequestMessage.CreateResponseMessage<TR>();
// responseMessage.Content = content;
// return responseMessage;
//}
#endregion
#region 消息处理
/// <summary>
/// OnExecuting
/// </summary>
[Obsolete("请使用异步方法 OnExecutingAsync()", true)]
public override void OnExecuting()
{
throw new MessageHandlerException("请使用异步方法 OnExecutingAsync()");
}
[Obsolete("请使用异步方法 OnExecutedAsync()", true)]
public override void OnExecuted()
{
throw new MessageHandlerException("请使用异步方法 OnExecutedAsync()");
}
#endregion }
}
}
View on GitHub (pinned to be573f6f94)