Skip to content

Restore OnError routing for NPC-sourced WhenPropertyChanged emissions; bump main to v10 preview#1

Closed
dwcullop wants to merge 1 commit into
mainfrom
bugfix/restore_error_handling
Closed

Restore OnError routing for NPC-sourced WhenPropertyChanged emissions; bump main to v10 preview#1
dwcullop wants to merge 1 commit into
mainfrom
bugfix/restore_error_handling

Conversation

@dwcullop

@dwcullop dwcullop commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

PR reactivemarbles#1111 fixed a TOCTOU race in WhenPropertyChanged / WhenValueChanged, but a follow-up commit in that PR stopped routing downstream exceptions through OnError. Because these emissions originate from an INotifyPropertyChanged callback, an unhandled OnNext throw escaped raw out of the property setter that raised PropertyChanged. Setting a property could throw because some unrelated observer misbehaved.

This restores the error routing on both the shallow (x => x.Prop) and deep-chain (x => x.A.B.Prop) paths.

What changed

  • SinglePropertySubscription.EmitCurrent and DeepChainSubscription.ProcessSignal again wrap the accessor read, chain walk, and the downstream OnNext in try/catch, routing any exception through OnError. A subscriber that supplied an error handler now observes the failure instead of it escaping into the setter.
  • Per Jake's review point on WhenPropertyChanged: don't drop events fired during subscribe reactivemarbles/DynamicData#1111, we deliberately do not swallow a throw from OnError itself. An unhandled downstream error (or a rethrowing error handler) still propagates, matching Subject<T>.OnNext semantics. This is the middle ground between the original swallow-everything behavior and the raw-escape behavior that shipped.
  • version.json: 9.5-preview -> 10.0-preview so main builds the next major preview.

Behavior

Scenario Before this PR (current main) After
Subscriber OnNext throws, has error handler escapes raw to setter, handler bypassed routed to OnError, setter safe
Subscriber OnNext throws, no error handler escapes to setter routed to OnError (no-op after detach), setter safe
Accessor throws, error handler rethrows propagates to setter propagates to setter (unchanged)

Tests

WhenPropertyChangedBehaviorFixture gains 4 tests (shallow + deep) covering the OnNext routing restore (RED on current main) and the non-swallow decision. Full Binding suite: 156 passed, 2 pre-existing skips.

Labels / breaking change

  • manual-version-edit: required by pr-version-check.yml for a human edit to version.json.
  • breaking-change: the major bump 9 -> 10, and the error-propagation behavior change, are both observable. Flagging so maintainers make the call.

…; bump main to v10 preview

PR reactivemarbles#1111 (WhenPropertyChanged race fix) rewrote the shallow and deep-chain observation paths and, in a follow-up commit, stopped routing downstream exceptions through OnError. Because these emissions originate from an INotifyPropertyChanged callback, an unhandled OnNext throw escaped raw out of the property setter that raised PropertyChanged.

Restore the try/catch that routes accessor, chain-walk, and downstream OnNext exceptions through OnError so a subscriber that supplied an error handler observes the failure and the setter stays safe. Per Jake's review point, do NOT swallow a throw from OnError itself: an unhandled downstream error (or a rethrowing error handler) still propagates, matching Subject<T>.OnNext semantics.

Also bump version.json from 9.5-preview to 10.0-preview so main builds the next major preview.

Adds regression tests in WhenPropertyChangedBehaviorFixture covering both the OnNext-routing restore (RED on current main) and the non-swallow decision, for the shallow and deep-chain paths.
@dwcullop dwcullop added manual-version-edit Deliberate human edit to version.json; bypasses the automation-owned version guard breaking-change Introduces a breaking change; requires a major version bump labels Jul 2, 2026
@dwcullop dwcullop closed this Jul 2, 2026
@dwcullop dwcullop deleted the bugfix/restore_error_handling branch July 2, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Introduces a breaking change; requires a major version bump manual-version-edit Deliberate human edit to version.json; bypasses the automation-owned version guard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant