{"record":{"id":"f688722a55f18a66","repo":"dotnet/reactive","slug":"end","errorCode":null,"errorMessage":"end","messagePattern":"end","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Async.cs","lineNumber":62,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TArg1\">The type of the first argument passed to the begin delegate.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the result returned by the end delegate.</typeparam>\n        /// <param name=\"begin\">The delegate that begins the asynchronous operation.</param>\n        /// <param name=\"end\">The delegate that ends the asynchronous operation.</param>\n        /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"begin\"/> or <paramref name=\"end\"/> is null.</exception>\n        /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>\n        [Obsolete(Constants_Linq.UseTaskFromAsyncPattern)]\n        public static Func<TArg1, IObservable<TResult>> FromAsyncPattern<TArg1, TResult>(Func<TArg1, AsyncCallback, object?, IAsyncResult> begin, Func<IAsyncResult, TResult> end)\n        {\n            if (begin == null)\n            {\n                throw new ArgumentNullException(nameof(begin));\n            }\n\n            if (end == null)\n            {\n                throw new ArgumentNullException(nameof(end));\n            }\n\n            return s_impl.FromAsyncPattern(begin, end);\n        }\n\n        /// <summary>\n        /// Converts a Begin/End invoke function pair into an asynchronous function.\n        /// </summary>\n        /// <typeparam name=\"TArg1\">The type of the first argument passed to the begin delegate.</typeparam>\n        /// <typeparam name=\"TArg2\">The type of the second argument passed to the begin delegate.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the result returned by the end delegate.</typeparam>\n        /// <param name=\"begin\">The delegate that begins the asynchronous operation.</param>\n        /// <param name=\"end\">The delegate that ends the asynchronous operation.</param>\n        /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"begin\"/> or <paramref name=\"end\"/> is null.</exception>\n        /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>\n        [Obsolete(Constants_Linq.UseTaskFromAsyncPattern)]\n        public static Func<TArg1, TArg2, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> begin, Func<IAsyncResult, TResult> end)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Async.cs#L44-L80","documentation":"The single-argument FromAsyncPattern<TArg1,TResult> overload throws ArgumentNullException('end') when the end delegate Func<IAsyncResult, TResult> is null. Both begin and end delegates are mandatory: end converts the IAsyncResult into the final result and completes the observable sequence. Validation happens when the wrapper Func is created.","triggerScenarios":"Observable.FromAsyncPattern<TArg1,TResult>(begin, null) - the end argument omitted or resolved to null.","commonSituations":"Wrapping legacy Begin/End pairs where only the Begin call was ported; conditional wiring code that leaves end unassigned; wrong generic type inference pushing developers toward the wrong overload.","solutions":["Supply the EndXxx method (or a lambda wrapping it) as the end delegate","Null-check delegates obtained dynamically before passing them","Use Observable.FromAsync with a Task-returning function instead of APM"],"exampleFix":"// before\nvar f = Observable.FromAsyncPattern<int, byte[]>(begin, null);\n// after\nvar f = Observable.FromAsyncPattern<int, byte[]>(begin, iar => stream.EndRead(iar));","handlingStrategy":"validation","validationCode":"if (begin == null || end == null) throw new InvalidOperationException(\"Both begin and end delegates are required\");\nvar f = Observable.FromAsyncPattern<TArg1, TResult>(begin, end);","typeGuard":"static bool ValidApmPair<TArg1,TResult>(Func<TArg1, AsyncCallback, object?, IAsyncResult> b, Func<IAsyncResult, TResult> e) => b != null && e != null;","tryCatchPattern":"try\n{\n    var f = Observable.FromAsyncPattern<TArg1, TResult>(begin, end);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"end\")\n{\n    // supply the end delegate\n}","preventionTips":["Port Begin/End pairs as complete units","Unit-test wrapper construction with real delegates","Use Task-based APIs to eliminate APM wiring"],"tags":["csharp","null-argument","rx","async"],"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"}