{"record":{"id":"58226c6b244beda5","repo":"EllanJiang/GameFramework","slug":"event-0-not-allow-multi-handler","errorCode":null,"errorMessage":"Event '{0}' not allow multi handler.","messagePattern":"Event '(.+?)' not allow multi handler\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/EventPool/EventPool.cs","lineNumber":153,"sourceCode":"        /// <summary>\n        /// 订阅事件处理函数。\n        /// </summary>\n        /// <param name=\"id\">事件类型编号。</param>\n        /// <param name=\"handler\">要订阅的事件处理函数。</param>\n        public void Subscribe(int id, EventHandler<T> handler)\n        {\n            if (handler == null)\n            {\n                throw new GameFrameworkException(\"Event handler is invalid.\");\n            }\n\n            if (!m_EventHandlers.Contains(id))\n            {\n                m_EventHandlers.Add(id, handler);\n            }\n            else if ((m_EventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler)\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Event '{0}' not allow multi handler.\", id));\n            }\n            else if ((m_EventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler))\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Event '{0}' not allow duplicate handler.\", id));\n            }\n            else\n            {\n                m_EventHandlers.Add(id, handler);\n            }\n        }\n\n        /// <summary>\n        /// 取消订阅事件处理函数。\n        /// </summary>\n        /// <param name=\"id\">事件类型编号。</param>\n        /// <param name=\"handler\">要取消订阅的事件处理函数。</param>\n        public void Unsubscribe(int id, EventHandler<T> handler)\n        {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/EventPool/EventPool.cs#L135-L171","documentation":"Subscribe throws this when the pool's EventPoolMode does not include AllowMultiHandler but a second handler is being registered for an event id that already has one. GameFramework's event pool intentionally restricts each event id to a single handler unless AllowMultiHandler is enabled at pool construction, to catch accidental overwrite-style subscription bugs.","triggerScenarios":"Calling Subscribe(id, handler) twice for the same id on a pool created with EventPoolMode.Default (or any mode without AllowMultiHandler); two different systems independently subscribing to the same custom event id; re-subscribing in OnEnable without unsubscribing in OnDisable.","commonSituations":"Duplicate event id constants defined in an enum; a UI panel that subscribes in OnEnable but forgets Unsubscribe in OnDisable, then re-subscribes on reopen; two game modules choosing the same int id for different events.","solutions":["Create the event pool with EventPoolMode.AllowMultiHandler if multiple handlers per event are intended.","Unsubscribe the previous handler before subscribing again for the same id.","Make sure each event id is unique — rename colliding enum constants.","Track subscription state (bool flag) so Subscribe is only called once per handler/id."],"exampleFix":"// before\nm_EventPool = new EventPool<GameEventEventArgs>(EventPoolMode.Default);\nm_EventPool.Subscribe(id, handler1);\nm_EventPool.Subscribe(id, handler2); // throws\n// after\nm_EventPool = new EventPool<GameEventEventArgs>(EventPoolMode.AllowMultiHandler);\nm_EventPool.Subscribe(id, handler1);\nm_EventPool.Subscribe(id, handler2);","handlingStrategy":"validation","validationCode":"if (eventPool.Check(id, handler) || HasAnyHandler(id))\n{\n    // already handled — skip or Unsubscribe first\n}\nelse\n{\n    eventPool.Subscribe(id, handler);\n}\n// or verify pool mode at startup:\nDebug.Assert((poolMode & EventPoolMode.AllowMultiHandler) != 0 || FirstSubscribe);","typeGuard":null,"tryCatchPattern":"try\n{\n    eventPool.Subscribe(id, handler);\n}\ncatch (GameFrameworkException ex) when (ex.Message.Contains(\"not allow multi handler\"))\n{\n    eventPool.Unsubscribe(id, existingHandler);\n    eventPool.Subscribe(id, handler);\n}","preventionTips":["Decide the multi-handler policy once when constructing the EventPool and document it.","Use unique event-id enum values per event; audit for duplicate ids.","Always pair Subscribe with Unsubscribe in enable/disable lifecycle methods.","Use Check(id, handler) before subscribing to detect existing handlers."],"tags":["event-pool","eventpoolmode","duplicate-subscription"],"backgroundTag":"unsupported-operation","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"}