{"record":{"id":"90df99f732a94828","repo":"JeffreySu/WeiXinMPSDK","slug":"argumentnullexception-options-is-null","errorCode":null,"errorMessage":"ArgumentNullException (options is null)","messagePattern":"ArgumentNullException \\(options is null\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceClient.cs","lineNumber":277,"sourceCode":"        /// <summary>\n        /// 在调用方未显式释放时尽力回收原生资源。\n        /// </summary>\n        ~MsgAuditFinanceClient()\n        {\n            ReleaseResources(false);\n        }\n\n        private static IMsgAuditFinanceNativeApi CreateNativeApi(MsgAuditFinanceOptions options)\n        {\n            ValidateOptions(options);\n            return new MsgAuditFinanceNativeApi(options.LibraryPath);\n        }\n\n        private static void ValidateOptions(MsgAuditFinanceOptions options)\n        {\n            if (options == null)\n            {\n                throw new ArgumentNullException(nameof(options));\n            }\n\n            ValidateRequiredText(options.CorpId, nameof(options.CorpId));\n            ValidateRequiredText(options.Secret, nameof(options.Secret));\n            if (options.TimeoutSeconds <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options.TimeoutSeconds),\n                    \"原生 SDK 网络请求超时时间必须大于 0 秒。\");\n            }\n        }\n\n        private static void ValidateRequiredText(string value, string parameterName)\n        {\n            if (string.IsNullOrWhiteSpace(value))\n            {\n                throw new ArgumentException(\"参数不能为空。\", parameterName);\n            }\n        }","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceClient.cs#L259-L295","documentation":"MsgAuditFinanceClient's constructor and CreateNativeApi call ValidateOptions, which rejects a null MsgAuditFinanceOptions instance with ArgumentNullException named 'options'. Configuration is mandatory: the client needs CorpId, Secret, timeout, and library path before it can initialize the native SDK.","triggerScenarios":"new MsgAuditFinanceClient(null) or constructing the client with an options variable that was never assigned (e.g. DI/binding failure yielding null).","commonSituations":"Config sections missing so options binding returns null, conditional factory methods returning null on some platforms, or copy-pasted constructor calls passing null explicitly.","solutions":["Pass a fully constructed MsgAuditFinanceOptions instance to the constructor","Load options from configuration and assert non-null before constructing the client","If using DI/config binding, verify the configuration section exists and is bound"],"exampleFix":"// before\nvar client = new MsgAuditFinanceClient(config.GetSection(\"MsgAudit\")?.Value == null ? null : BuildOptions());\n// after\nvar options = BuildOptions() ?? throw new InvalidOperationException(\"MsgAudit finance options missing from config\");\nvar client = new MsgAuditFinanceClient(options);","handlingStrategy":"validation","validationCode":"if (options is null) throw new InvalidOperationException(\"MsgAuditFinanceOptions must be configured before creating MsgAuditFinanceClient\");","typeGuard":"bool HasOptions(MsgAuditFinanceOptions? o) => o is not null;","tryCatchPattern":"try { var client = new MsgAuditFinanceClient(options); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"options\") { /* load config and retry */ }","preventionTips":["Centralize options construction in one factory that never returns null","Validate configuration at application startup, not at first client use","Use required properties/init setters so options cannot be default-constructed silently"],"tags":["csharp","argument-null","configuration","weixin-work"],"backgroundTag":"null-argument","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"}