{"record":{"id":"572f6b1c32f4f153","repo":"dotnet/reactive","slug":"source-observable-time","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs","lineNumber":850,"sourceCode":"        /// <summary>\n        /// Samples the observable sequence at each interval.\n        /// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence to sample.</param>\n        /// <param name=\"interval\">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>\n        /// <returns>Sampled observable sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"interval\"/> is less than TimeSpan.Zero.</exception>\n        /// <remarks>\n        /// Specifying a TimeSpan.Zero value for <paramref name=\"interval\"/> doesn't guarantee all source sequence elements will be preserved. This is a side-effect\n        /// of the asynchrony introduced by the scheduler, where the sampling action may not execute immediately, despite the TimeSpan.Zero due time.\n        /// </remarks>\n        public static IObservable<TSource> Sample<TSource>(this IObservable<TSource> source, TimeSpan interval)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (interval < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(interval));\n            }\n\n            return s_impl.Sample(source, interval);\n        }\n\n        /// <summary>\n        /// Samples the observable sequence at each interval, using the specified scheduler to run sampling timers.\n        /// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence to sample.</param>\n        /// <param name=\"interval\">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>\n        /// <param name=\"scheduler\">Scheduler to run the sampling timer on.</param>","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs#L832-L868","documentation":"The Sample<TSource>(IObservable<TSource>, TimeSpan) operator throws ArgumentNullException when the source observable is null. Rx operators validate all reference arguments eagerly at call time so a bad composition fails immediately at the call site instead of surfacing as a null reference when subscribing. This is a programmer error, not a runtime condition.","triggerScenarios":"Calling Observable.Sample<TSource>(null, someTimeSpan) — i.e., the source argument is a null IObservable<TSource> reference, typically from an uninitialized field, a failed factory method, or a dictionary miss.","commonSituations":"Storing an IObservable in a field that was never assigned; a config-driven factory returning null; chaining LINQ-style operators where an earlier method returned null instead of an empty sequence; refactoring where a DI container failed to inject the observable.","solutions":["Ensure the source observable is assigned before calling Sample; trace where the null reference originates.","Guard the call site: if (source == null) throw or substitute Observable.Empty<TSource>().","Fix the producing code so it never returns null — return Observable.Empty<TSource>() instead."],"exampleFix":"// before\nIObservable<int> src = GetStream(); // may return null\nvar sampled = src.Sample(TimeSpan.FromSeconds(1)); // ArgumentNullException\n\n// after\nvar src = GetStream() ?? Observable.Empty<int>();\nvar sampled = src.Sample(TimeSpan.FromSeconds(1));","handlingStrategy":"validation","validationCode":"if (source == null)\n    throw new ArgumentException(\"source must not be null before calling Sample\");\nif (interval < TimeSpan.Zero)\n    throw new ArgumentException(\"interval must be non-negative\");\nvar sampled = source.Sample(interval);","typeGuard":"static bool IsValidSampleInput<TSource>(IObservable<TSource> source, TimeSpan interval) =>\n    source != null && interval >= TimeSpan.Zero;","tryCatchPattern":"try\n{\n    var sampled = source.Sample(interval);\n}\ncatch (ArgumentNullException) { /* source was null — fix producer */ }\ncatch (ArgumentOutOfRangeException) { /* negative interval */ }","preventionTips":["Never let factory methods return null observables — return Observable.Empty<T>().","Initialize observable fields at construction, not lazily at use.","Validate TimeSpan parameters at application boundaries before composing operators."],"tags":["argument-null","rx","sample","argument-validation"],"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"}