{"record":{"id":"00627c59850fbad1","repo":"JeffreySu/WeiXinMPSDK","slug":"ex-message","errorCode":null,"errorMessage":"{ex.Message}","messagePattern":"\\{ex\\.Message\\}","errorType":"exception","errorClass":"WeixinMenuException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/CommonAPIs/CommonApi.Menu.cs","lineNumber":439,"sourceCode":"                                subButton.sub_button.Add(new SingleScancodeWaitmsgButton()\n                                {\n                                    name = subSubButton.name,\n                                    key = subSubButton.key,\n                                    type = subSubButton.type\n                                });\n                            }\n                        }\n                    }\n                }\n\n                result = new GetMenuResult()\n                {\n                    menu = bg\n                };\n            }\n            catch (Exception ex)\n            {\n                throw new WeixinMenuException(ex.Message, ex);\n            }\n            return result;\n        }\n\n        #endregion\n\n        /// <summary>\n        /// 删除菜单\n        /// </summary>\n        /// <param name=\"accessToken\">调用接口凭证</param>\n        /// <param name=\"agentId\">企业应用的id，整型。可在应用的设置页面查看</param>\n        /// <returns></returns>\n        public static WorkJsonResult DeleteMenu(string accessTokenOrAppId, int agentId)\n        {\n            return ApiHandlerWapper.TryCommonApi(accessToken =>\n            {\n                var url = string.Format(Config.ApiWorkHost + \"/cgi-bin/menu/delete?access_token={0}&agentid={1}\", accessToken.AsUrlData(), agentId);\n                var result = CommonJsonSend.Send<WorkJsonResult>(null, url, null, CommonJsonSendType.GET);","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/CommonAPIs/CommonApi.Menu.cs#L421-L457","documentation":"GetMenuFromJsonResult wraps ANY exception thrown while converting the full menu JSON into the button graph in a WeixinMenuException whose message is the original ex.Message. This includes the key-validation errors, JSON/serializer failures, and unexpected null structures. It is a catch-all so callers only need to handle WeixinMenuException, but the message may be less specific than the underlying cause.","triggerScenarios":"Any failure inside GetMenuFromJsonResult (called by GetMenu): malformed/unexpected menu JSON shape, null button containers where the parser expects arrays, or the inner WeixinMenuException key validations bubbling up to the catch block.","commonSituations":"WeChat Work changes the menu response format; corrupted or truncated JSON stored/returned; developer-supplied menu objects with unexpected nulls during custom parsing; version drift between library expectations and server response.","solutions":["Catch WeixinMenuException and inspect both the message and the InnerException to find the real cause.","Log the raw menu JSON (jsonString passed to GetMenu) to compare against the expected GetMenuResultFull schema.","Update the Senparc.Weixin.Work package to the latest version in case the server response format changed.","Fix the underlying menu data so parsing succeeds (valid types, keys, non-null containers)."],"exampleFix":"// before\ncatch (WeixinMenuException ex) { throw ex; }\n\n// after\ncatch (WeixinMenuException ex)\n{\n    _logger.LogError(ex, \"Menu parse failed: {Msg} / {Inner}\", ex.Message, ex.InnerException?.Message);\n    throw;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var result = CommonApi.GetMenu(token, agentId); }\ncatch (WeixinMenuException ex)\n{\n    // always inspect InnerException — message may be a wrapped cause\n    Log(ex, ex.InnerException);\n}","preventionTips":["Never discard InnerException when rethrowing WeixinMenuException","Log the raw menu JSON alongside the exception for diagnosis","Keep the Senparc.Weixin.Work package updated against API format drift","Treat menu parse failures as data problems first, code problems second"],"tags":["wechat-work","menu","parsing","wrapped-exception"],"backgroundTag":"unexpected-response-shape","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}