JeffreySu/WeiXinMPSDK · error · InvalidDataException

无法解析 Finance SDK 返回的会话内容 JSON。

Error message

无法解析 Finance SDK 返回的会话内容 JSON。

What it means

After a successful native call, GetChatData deserializes the slice JSON via System.Text.Json source-generated JsonSerializer. If deserialization returns null (possible when the JSON encodes a null value), the client throws InvalidDataException because it cannot distinguish a valid empty result from a malformed payload.

Solutions

  1. Capture the raw JSON (result.raw_json is attached on success) — log json before parse to inspect the payload
  2. Ensure MsgAuditFinanceJsonSerializerContext is used exactly as shipped and the type is registered (no trimming/AOT stripping)
  3. Wrap the call in try/catch for InvalidDataException/JsonException and treat as retryable pull
  4. Upgrade the SDK package if the SDK payload schema changed and the target type no longer matches

Example fix

// before
var result = client.GetChatData(seq, 1000);
Process(result.ChatData);
// after
try { var result = client.GetChatData(seq, 1000); Process(result.ChatData); }
catch (InvalidDataException ex) { _logger.LogWarning(ex, "Unparseable finance payload, retrying"); ScheduleRetry(seq); }
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check payload looks like an object
if (json != null && json.Trim() == "null") throw new InvalidOperationException("Finance SDK returned null payload");

Try / catch

try { var data = client.GetChatData(seq, 1000); } catch (InvalidDataException ex) { log.Warn(ex, "Unparseable finance payload"); ScheduleRetry(seq); }

Prevention

When it happens

Trigger: The Finance SDK returns JSON that deserializes to null for MsgAuditFinanceChatDataResult — e.g. payload literally "null", or a serializer/source-generator context mismatch (type not registered, trimmed assembly).

Common situations: AOT/trimming dropping the MsgAuditFinanceChatDataResult metadata so Deserialize returns null; SDK returning unusual payloads; custom JsonSerializerOptions missing the source-gen context.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceClient.cs:108

                var slice = _nativeApi.NewSlice();
                EnsureNativeHandle(slice, "NewSlice");
                try
                {
                    var errorCode = _nativeApi.GetChatData(_sdk, sequence, limit, _proxy,
                        _proxyPassword, _timeoutSeconds, slice);
                    ThrowIfNativeError(errorCode, "GetChatData");

                    var json = _nativeApi.GetSliceContent(slice);
                    if (string.IsNullOrWhiteSpace(json))
                    {
                        throw new InvalidDataException("Finance SDK 返回的会话内容为空。");
                    }

                    var result = JsonSerializer.Deserialize(json,
                        MsgAuditFinanceJsonSerializerContext.Default.MsgAuditFinanceChatDataResult);
                    if (result == null)
                    {
                        throw new InvalidDataException("无法解析 Finance SDK 返回的会话内容 JSON。");
                    }

                    result.raw_json = json;
                    return result;
                }
                finally
                {
                    _nativeApi.FreeSlice(slice);
                }
            }
        }

        /// <summary>
        /// 使用官方 Finance SDK 解密一条会话消息。
        /// </summary>
        /// <param name="decryptedRandomKey">
        /// 对 <c>encrypt_random_key</c> 完成 Base64 解码并使用企业 RSA 私钥按 PKCS#1 解密后得到的随机密钥。
        /// </param>

View on GitHub (pinned to be573f6f94)