Skip to content

Conversation

@kitten
Copy link
Contributor

@kitten kitten commented May 21, 2025

Summary:

Calls to create timers should return sequential ids (integers greater than zero in the spec's words). This regressed in the TimerManager implementation, which instead starts at zero inclusively.

This has two side-effects for code assuming a spec-compliant implementation of setTimeout and setInterval:

  • Calls to clearTimeout(0) or clearInterval(0) will potentially cancel scheduled timers, although it's supposed to be a noop
  • Predicates like if (timeoutId) will fail since they assume non-negative ids

The change in this PR is to align with WHATWG HTML 8.6.2 (Timers): https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

otherwise, let id be an implementation-defined integer that is greater than zero and does not already exist in global's map of setTimeout and setInterval IDs.

Specifically,

  • we should return 0 to indicate that no timer was scheduled
  • we should start generating timer IDs at 1 instead of 0

This was previously raised in review comments here: https://github.com/facebook/react-native/pull/45092/files#r1650790008

The spec-incompliant behaviour was raised in an issue here: apollographql/apollo-client#12632 (comment)

This PR does not,

  • add bounds checking on timerIndex_ and add a search of an available id that isn't in the unordered map
  • exclude 0 from being an accepted TimerHandle in TimerManager::createTimer or TimerManager::deleteTimer since the above bounds checking hasn't been added either

Changelog:

[GENERAL] [FIXED] - Align timer IDs and timer function argument error handling with web standards.

Test Plan:

  • Run setTimeout / setInterval; before applied changes the timeout for the first timer will be 0
  • Run setTimeout(null); before applied changes the timer ID will be non-zero
  • Run setInterval(null); before applied changes an error will be thrown rather than 0 being returned

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Expo Partner: Expo Partner labels May 21, 2025
@kitten kitten changed the title fix: Align TimerManager sequential ids and function error handling on with web standard fix: Align TimerManager sequential ids and function error handling with web standard May 21, 2025
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label May 21, 2025
@facebook-github-bot
Copy link
Contributor

@rshest has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link
Contributor

@cipolleschi cipolleschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! :D

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label May 22, 2025
@facebook-github-bot
Copy link
Contributor

@rshest merged this pull request in 480a464.

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @kitten in 480a464

When will my fix make it into a release? | How to file a pick request?

react-native-bot pushed a commit that referenced this pull request May 23, 2025
…with web standard (#51500)

Summary:
Calls to create timers should return sequential ids (integers greater than zero in the spec's words). This regressed in the `TimerManager` implementation, which instead starts at zero inclusively.

This has two side-effects for code assuming a spec-compliant implementation of `setTimeout` and `setInterval`:
- Calls to `clearTimeout(0)` or `clearInterval(0)` will potentially cancel scheduled timers, although it's supposed to be a noop
- Predicates like `if (timeoutId)` will fail since they assume non-negative ids

The change in this PR is to align with WHATWG HTML 8.6.2 (Timers): https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

> otherwise, let id be an [implementation-defined](https://infra.spec.whatwg.org/#implementation-defined) integer that is **greater than zero** and does not already [exist](https://infra.spec.whatwg.org/#map-exists) in global's [map of setTimeout and setInterval IDs](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#map-of-settimeout-and-setinterval-ids).

Specifically,
- we should return `0` to indicate that no timer was scheduled
- we should start generating timer IDs at `1` instead of `0`

This was previously raised in review comments here: https://github.com/facebook/react-native/pull/45092/files#r1650790008

The spec-incompliant behaviour was raised in an issue here: apollographql/apollo-client#12632 (comment)

This PR does not,
- add bounds checking on `timerIndex_` and add a search of an available id that isn't in the unordered map
- exclude `0` from being an accepted `TimerHandle` in `TimerManager::createTimer` or `TimerManager::deleteTimer` since the above bounds checking hasn't been added either

## Changelog:

[GENERAL] [FIXED] - Align timer IDs and timer function argument error handling with web standards.

Pull Request resolved: #51500

Test Plan:
- Run `setTimeout` / `setInterval`; before applied changes the timeout for the first timer will be `0`
- Run `setTimeout(null)`; before applied changes the timer ID will be non-zero
- Run `setInterval(null)`; before applied changes an error will be thrown rather than `0` being returned

Reviewed By: cipolleschi

Differential Revision: D75145909

Pulled By: rshest

fbshipit-source-id: 6646439abd29cf3cfa9e5cf0a57448e3b7cd1b48
@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @kitten in 24131c6

When will my fix make it into a release? | How to file a pick request?

react-native-bot pushed a commit that referenced this pull request Jun 4, 2025
…with web standard (#51500)

Summary:
Calls to create timers should return sequential ids (integers greater than zero in the spec's words). This regressed in the `TimerManager` implementation, which instead starts at zero inclusively.

This has two side-effects for code assuming a spec-compliant implementation of `setTimeout` and `setInterval`:
- Calls to `clearTimeout(0)` or `clearInterval(0)` will potentially cancel scheduled timers, although it's supposed to be a noop
- Predicates like `if (timeoutId)` will fail since they assume non-negative ids

The change in this PR is to align with WHATWG HTML 8.6.2 (Timers): https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

> otherwise, let id be an [implementation-defined](https://infra.spec.whatwg.org/#implementation-defined) integer that is **greater than zero** and does not already [exist](https://infra.spec.whatwg.org/#map-exists) in global's [map of setTimeout and setInterval IDs](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#map-of-settimeout-and-setinterval-ids).

Specifically,
- we should return `0` to indicate that no timer was scheduled
- we should start generating timer IDs at `1` instead of `0`

This was previously raised in review comments here: https://github.com/facebook/react-native/pull/45092/files#r1650790008

The spec-incompliant behaviour was raised in an issue here: apollographql/apollo-client#12632 (comment)

This PR does not,
- add bounds checking on `timerIndex_` and add a search of an available id that isn't in the unordered map
- exclude `0` from being an accepted `TimerHandle` in `TimerManager::createTimer` or `TimerManager::deleteTimer` since the above bounds checking hasn't been added either

## Changelog:

[GENERAL] [FIXED] - Align timer IDs and timer function argument error handling with web standards.

Pull Request resolved: #51500

Test Plan:
- Run `setTimeout` / `setInterval`; before applied changes the timeout for the first timer will be `0`
- Run `setTimeout(null)`; before applied changes the timer ID will be non-zero
- Run `setInterval(null)`; before applied changes an error will be thrown rather than `0` being returned

Reviewed By: cipolleschi

Differential Revision: D75145909

Pulled By: rshest

fbshipit-source-id: 6646439abd29cf3cfa9e5cf0a57448e3b7cd1b48
@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @kitten in 942422c

When will my fix make it into a release? | How to file a pick request?

react-native-bot pushed a commit that referenced this pull request Jul 1, 2025
…with web standard (#51500)

Summary:
Calls to create timers should return sequential ids (integers greater than zero in the spec's words). This regressed in the `TimerManager` implementation, which instead starts at zero inclusively.

This has two side-effects for code assuming a spec-compliant implementation of `setTimeout` and `setInterval`:
- Calls to `clearTimeout(0)` or `clearInterval(0)` will potentially cancel scheduled timers, although it's supposed to be a noop
- Predicates like `if (timeoutId)` will fail since they assume non-negative ids

The change in this PR is to align with WHATWG HTML 8.6.2 (Timers): https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

> otherwise, let id be an [implementation-defined](https://infra.spec.whatwg.org/#implementation-defined) integer that is **greater than zero** and does not already [exist](https://infra.spec.whatwg.org/#map-exists) in global's [map of setTimeout and setInterval IDs](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#map-of-settimeout-and-setinterval-ids).

Specifically,
- we should return `0` to indicate that no timer was scheduled
- we should start generating timer IDs at `1` instead of `0`

This was previously raised in review comments here: https://github.com/facebook/react-native/pull/45092/files#r1650790008

The spec-incompliant behaviour was raised in an issue here: apollographql/apollo-client#12632 (comment)

This PR does not,
- add bounds checking on `timerIndex_` and add a search of an available id that isn't in the unordered map
- exclude `0` from being an accepted `TimerHandle` in `TimerManager::createTimer` or `TimerManager::deleteTimer` since the above bounds checking hasn't been added either

## Changelog:

[GENERAL] [FIXED] - Align timer IDs and timer function argument error handling with web standards.

Pull Request resolved: #51500

Test Plan:
- Run `setTimeout` / `setInterval`; before applied changes the timeout for the first timer will be `0`
- Run `setTimeout(null)`; before applied changes the timer ID will be non-zero
- Run `setInterval(null)`; before applied changes an error will be thrown rather than `0` being returned

Reviewed By: cipolleschi

Differential Revision: D75145909

Pulled By: rshest

fbshipit-source-id: 6646439abd29cf3cfa9e5cf0a57448e3b7cd1b48
@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @kitten in 26b70c2

When will my fix make it into a release? | How to file a pick request?

fabriziocucci pushed a commit that referenced this pull request Jul 9, 2025
…with web standard (#51500)

Summary:
Calls to create timers should return sequential ids (integers greater than zero in the spec's words). This regressed in the `TimerManager` implementation, which instead starts at zero inclusively.

This has two side-effects for code assuming a spec-compliant implementation of `setTimeout` and `setInterval`:
- Calls to `clearTimeout(0)` or `clearInterval(0)` will potentially cancel scheduled timers, although it's supposed to be a noop
- Predicates like `if (timeoutId)` will fail since they assume non-negative ids

The change in this PR is to align with WHATWG HTML 8.6.2 (Timers): https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

> otherwise, let id be an [implementation-defined](https://infra.spec.whatwg.org/#implementation-defined) integer that is **greater than zero** and does not already [exist](https://infra.spec.whatwg.org/#map-exists) in global's [map of setTimeout and setInterval IDs](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#map-of-settimeout-and-setinterval-ids).

Specifically,
- we should return `0` to indicate that no timer was scheduled
- we should start generating timer IDs at `1` instead of `0`

This was previously raised in review comments here: https://github.com/facebook/react-native/pull/45092/files#r1650790008

The spec-incompliant behaviour was raised in an issue here: apollographql/apollo-client#12632 (comment)

This PR does not,
- add bounds checking on `timerIndex_` and add a search of an available id that isn't in the unordered map
- exclude `0` from being an accepted `TimerHandle` in `TimerManager::createTimer` or `TimerManager::deleteTimer` since the above bounds checking hasn't been added either

## Changelog:

[GENERAL] [FIXED] - Align timer IDs and timer function argument error handling with web standards.

Pull Request resolved: #51500

Test Plan:
- Run `setTimeout` / `setInterval`; before applied changes the timeout for the first timer will be `0`
- Run `setTimeout(null)`; before applied changes the timer ID will be non-zero
- Run `setInterval(null)`; before applied changes an error will be thrown rather than `0` being returned

Reviewed By: cipolleschi

Differential Revision: D75145909

Pulled By: rshest

fbshipit-source-id: 6646439abd29cf3cfa9e5cf0a57448e3b7cd1b48
@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @kitten in 157cf11

When will my fix make it into a release? | How to file a pick request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants