{"record":{"id":"48801c2f03da1bf4","repo":"JeffreySu/WeiXinMPSDK","slug":"brandapicredentials-tenpayhttphandler","errorCode":null,"errorMessage":"brandApiCredentials","messagePattern":"brandApiCredentials","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayHttpHandler.cs","lineNumber":85,"sourceCode":"        //    InnerHandler = new HttpClientHandler();\n\n        //    this.merchantId = merchantId;\n        //    this.serialNo = merchantSerialNo;\n        //    this.privateKey = privateKey;\n        //}\n\n        //TODO: 此处重构使用ISenparcWeixinSettingForTenpayV3初始化实例\n        private readonly ISenparcWeixinSettingForTenpayV3 _tenpayV3Setting;\n        private readonly TenPayBrandApiCredentials _brandApiCredentials;\n\n        public TenPayHttpHandler(ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3 = null)\n            : this(senparcWeixinSettingForTenpayV3, null)\n        {\n        }\n\n        internal TenPayHttpHandler(TenPayBrandApiCredentials brandApiCredentials)\n            : this(null, brandApiCredentials ??\n                throw new ArgumentNullException(nameof(brandApiCredentials)))\n        {\n        }\n\n        private TenPayHttpHandler(\n            ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpayV3,\n            TenPayBrandApiCredentials brandApiCredentials)\n        {\n            InnerHandler = new HttpClientHandler();\n\n            _brandApiCredentials = brandApiCredentials;\n            if (_brandApiCredentials != null)\n            {\n                return;\n            }\n\n            _tenpayV3Setting = senparcWeixinSettingForTenpayV3 ?? Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;\n\n            if (!_tenpayV3Setting.EncryptionType.HasValue)","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayHttpHandler.cs#L67-L103","documentation":"The internal TenPayHttpHandler(TenPayBrandApiCredentials) constructor uses a throw-expression on its argument, so passing null for brandApiCredentials throws ArgumentNullException with param name 'brandApiCredentials'. Brand credentials are mandatory for this constructor overload.","triggerScenarios":"Calling new TenPayHttpHandler((TenPayBrandApiCredentials)null) directly, or via DI/factory where the TenPayBrandApiCredentials registration resolved to null.","commonSituations":"DI container returning null for an unregistered TenPayBrandApiCredentials; a factory method returning null when brand config is absent; casting/overload resolution picking the brand-credentials overload unintentionally with a null literal.","solutions":["Construct a valid TenPayBrandApiCredentials before creating the handler.","If brand credentials are optional, use the setting-based constructor TenPayHttpHandler(ISenparcWeixinSettingForTenpayV3) or the two-argument private path via the public overload instead.","Check DI registrations so TenPayBrandApiCredentials is registered and configured.","Null-check the credentials at the call site to produce a clearer application-level error."],"exampleFix":"// before\nvar handler = new TenPayHttpHandler((TenPayBrandApiCredentials)null);\n// after\nvar creds = new TenPayBrandApiCredentials(mchId, serial, publicKeyPem, privateKeyPem);\nvar handler = new TenPayHttpHandler(creds);","handlingStrategy":"validation","validationCode":"if (brandCredentials == null)\n    throw new InvalidOperationException(\"Brand credentials must be constructed before creating TenPayHttpHandler.\");\nvar handler = new TenPayHttpHandler(brandCredentials);","typeGuard":"bool HasBrandCredentials(TenPayBrandApiCredentials? c) => c is not null;","tryCatchPattern":"try { handler = new TenPayHttpHandler(brandCredentials); }\ncatch (ArgumentNullException ex) { logger.LogError(ex, \"Brand credentials were null — check DI registration\"); throw; }","preventionTips":["Register TenPayBrandApiCredentials in DI before registering the handler.","Null-check factory outputs before constructing handlers.","Use the settings-based constructor when brand credentials are optional.","Fail fast at startup if brand credentials are required but missing."],"tags":["null-argument","configuration","dependency-injection"],"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"}