{"record":{"id":"8652992e0a485c45","repo":"dotnet/reactive","slug":"addhandler-windowsobservable-events","errorCode":null,"errorMessage":"addHandler","messagePattern":"addHandler","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/WindowsObservable.Events.cs","lineNumber":30,"sourceCode":"    /// </summary>\n    [CLSCompliant(false)]\n    public static partial class WindowsObservable\n    {\n        /// <summary>\n        /// Converts a typed event, conforming to the standard event pattern, to an observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSender\">The type of the sender that raises the event.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the event data generated by the event.</typeparam>\n        /// <param name=\"addHandler\">Action that attaches the given event handler to the underlying .NET event.</param>\n        /// <param name=\"removeHandler\">Action that detaches the given event handler from the underlying .NET event.</param>\n        /// <returns>The observable sequence that contains data representations of invocations of the underlying typed event.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"addHandler\"/> or <paramref name=\"removeHandler\"/> is null.</exception>\n        /// <seealso cref=\"ToEventPattern\"/>\n        public static IObservable<EventPattern<TSender, TResult>> FromEventPattern<TSender, TResult>(Action<TypedEventHandler<TSender, TResult>> addHandler, Action<TypedEventHandler<TSender, TResult>> removeHandler)\n        {\n            if (addHandler == null)\n            {\n                throw new ArgumentNullException(nameof(addHandler));\n            }\n\n            if (removeHandler == null)\n            {\n                throw new ArgumentNullException(nameof(removeHandler));\n            }\n\n            return Observable.Create<EventPattern<TSender, TResult>>(observer =>\n            {\n                var h = new TypedEventHandler<TSender, TResult>((sender, args) =>\n                {\n                    observer.OnNext(new EventPattern<TSender, TResult>(sender, args));\n                });\n\n                addHandler(h);\n\n                return () =>\n                {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/WindowsObservable.Events.cs#L12-L48","documentation":"FromEventPattern throws ArgumentNullException when the addHandler delegate used to register a WinRT TypedEventHandler is null. Rx validates both subscription delegates eagerly so event wiring errors appear at operator construction time.","triggerScenarios":"Calling Observable.FromEventPattern<TSender,TResult>(addHandler, removeHandler) with a null addHandler Action<TypedEventHandler<TSender,TResult>>, e.g. passing a method group on an object that was null or a delegate variable that was never assigned.","commonSituations":"Wiring WinRT UI events through reflection-derived delegates where the MethodInfo lookup returned null; refactoring renamed a handler registration method without updating the delegate reference.","solutions":["Pass a valid addHandler delegate, typically (h) => target.EventName += h","Confirm the object whose event is being subscribed is non-null before building the delegate","Avoid caching delegates in fields that may remain null until initialization completes","Use a static lambda so the compiler guarantees a non-null delegate instance"],"exampleFix":"// before\nAction<TypedEventHandler<Button, RoutedEventArgs>> add = null;\nObservable.FromEventPattern<Button, RoutedEventArgs>(add, remove);\n// after\nObservable.FromEventPattern<Button, RoutedEventArgs>(\n    h => button.Click += h,\n    h => button.Click -= h);","handlingStrategy":"validation","validationCode":"if (addHandler == null) throw new ArgumentNullException(nameof(addHandler));\nif (removeHandler == null) throw new ArgumentNullException(nameof(removeHandler));","typeGuard":"static bool CanWireEvents<T>(Action<T> add, Action<T> remove) => add != null && remove != null;","tryCatchPattern":"try { var obs = Observable.FromEventPattern<TSender, TResult>(add, remove); }\ncatch (ArgumentNullException ex) { Log($\"Bad event wiring: {ex.ParamName}\"); }","preventionTips":["Always write add/remove as inline lambdas: h => target.Event += h, h => target.Event -= h","Never cache handler delegates in fields that may be null at wiring time","Verify the event source object is non-null before FromEventPattern","Prefer lambda wrappers over reflection-created delegates"],"tags":["rx","null-argument","events","winrt"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}