{"record":{"id":"15820fe77df8d1e3","repo":"EllanJiang/GameFramework","slug":"event-is-invalid","errorCode":null,"errorMessage":"Event is invalid.","messagePattern":"Event is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/EventPool/EventPool.cs","lineNumber":222,"sourceCode":"        /// <summary>\n        /// 设置默认事件处理函数。\n        /// </summary>\n        /// <param name=\"handler\">要设置的默认事件处理函数。</param>\n        public void SetDefaultHandler(EventHandler<T> handler)\n        {\n            m_DefaultHandler = handler;\n        }\n\n        /// <summary>\n        /// 抛出事件，这个操作是线程安全的，即使不在主线程中抛出，也可保证在主线程中回调事件处理函数，但事件会在抛出后的下一帧分发。\n        /// </summary>\n        /// <param name=\"sender\">事件源。</param>\n        /// <param name=\"e\">事件参数。</param>\n        public void Fire(object sender, T e)\n        {\n            if (e == null)\n            {\n                throw new GameFrameworkException(\"Event is invalid.\");\n            }\n\n            Event eventNode = Event.Create(sender, e);\n            lock (m_Events)\n            {\n                m_Events.Enqueue(eventNode);\n            }\n        }\n\n        /// <summary>\n        /// 抛出事件立即模式，这个操作不是线程安全的，事件会立刻分发。\n        /// </summary>\n        /// <param name=\"sender\">事件源。</param>\n        /// <param name=\"e\">事件参数。</param>\n        public void FireNow(object sender, T e)\n        {\n            if (e == null)\n            {","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/EventPool/EventPool.cs#L204-L240","documentation":"EventPool.Fire validates that the event argument object e is not null before enqueuing it for deferred dispatch. A null event payload cannot carry an event id (e.Id) for routing, so the library throws GameFrameworkException immediately at the Fire call site.","triggerScenarios":"Calling Fire(object sender, T e) with e == null, typically from a helper that builds the event args conditionally, or passing a null reference from an uninitialized event-args variable.","commonSituations":"A factory/ReferencePool.Get call returning null when the event args class isn't pooled; refactored code that removed event args creation but left Fire(eventArgs) in place; generic wrappers passing default(T) which is null for reference types.","solutions":["Create a valid event args instance (e.g. via ReferencePool.Acquire) before calling Fire.","Add a null check at the call site or in wrapper code so a null never reaches Fire.","Fix the event args factory that returned null.","If the event legitimately has no data, use an existing non-null args type instead of null."],"exampleFix":"// before\nOpenUIEventArgs e = GetArgsMaybeNull();\nm_EventComponent.Fire(this, e);\n// after\nOpenUIEventArgs e = GetArgsMaybeNull();\nif (e != null) { m_EventComponent.Fire(this, e); }","handlingStrategy":"validation","validationCode":"if (eventArgs == null) throw new InvalidOperationException(\"Event args must be created before Fire.\"); eventComponent.Fire(sender, eventArgs);","typeGuard":"static bool IsValidArgs<T>(T e) where T : class => e != null;","tryCatchPattern":"try { pool.Fire(sender, e); } catch (GameFrameworkException ex) { Log.Error(\"Attempted to fire a null event: {0}\", ex.Message); }","preventionTips":["Always acquire event args from ReferencePool before firing","Add null checks in wrapper/helper fire methods","Avoid generic fire APIs that can receive default(T)"],"tags":["event-pool","null-argument","fire","gameframework","csharp"],"backgroundTag":"null-argument","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}