JeffreySu/WeiXinMPSDK · error · MessageHandlerException

请使用异步方法 OnExecutedAsync()

Error message

请使用异步方法 OnExecutedAsync()

What it means

The synchronous OnExecuted override in the MP MessageHandler is marked [Obsolete(..., true)] and always throws MessageHandlerException, mirroring error 56 but for the post-processing hook. The library only supports the async lifecycle: logic that used to run after message handling must live in OnExecutedAsync.

Solutions

  1. Use the async pipeline (ExecuteAsync) so OnExecutedAsync runs instead of the throwing OnExecuted.
  2. Relocate post-processing logic from OnExecuted overrides into OnExecutedAsync in your handler subclass.
  3. Search and update all call sites flagged by the compiler as obsolete-with-error for OnExecuted.
  4. If a third-party wrapper calls the sync hooks, upgrade or replace that wrapper with an async-compatible one.

Example fix

// before
messageHandler.Execute();
messageHandler.OnExecuted();

// after
await messageHandler.ExecuteAsync(cancellationToken);

public override async Task OnExecutedAsync(CancellationToken ct)
{
    // post-processing here
}
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure no code path references the sync hook
if (typeof(MyHandler).GetMethod("OnExecuted", Type.EmptyTypes) != null)
    throw new InvalidOperationException("Override OnExecutedAsync, not OnExecuted");

Type guard

bool IsPostProcessingAsync(MyHandler h) =>
    h.GetType().GetMethod("OnExecutedAsync", new[] { typeof(CancellationToken) })
        .GetBaseDefinition().DeclaringType != typeof(object);

Try / catch

try { await messageHandler.ExecuteAsync(ct); }
catch (MessageHandlerException ex) when (ex.Message.Contains("OnExecutedAsync"))
{
    logger.LogError(ex, "Sync OnExecuted invoked; migrate to ExecuteAsync");
    throw;
}

Prevention

When it happens

Trigger: Calling messageHandler.OnExecuted() directly, overriding it and invoking base behavior, or running a legacy synchronous Execute pipeline that still calls OnExecuted after message handling completes.

Common situations: Upgraded Senparc.Weixin packages where old sync controller code (commonly in ASP.NET WeixinController or WxOpen samples) still invokes the sync pipeline; copy-pasted legacy sample code that performs post-processing via OnExecuted.

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


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/a2fc1c805a4fee9e. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.MP/Senparc.Weixin.MP/MessageHandlers/MessageHandler.cs:364

        //}

        #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)