SEPURI-SAI-KRISHNA opened a new pull request, #21733:
URL: https://github.com/apache/echarts/pull/21733

   <!-- Please fill in the following information to help us review your PR more 
efficiently. -->
   
   ## Brief Information
   
   This pull request is in the type of:
   
   - [x] bug fixing
   - [ ] new feature
   - [ ] others
   
   
   
   ### What does this PR do?
   
   Clears the tooltip's pending `setTimeout` handles when the tooltip view is 
disposed, so a delayed callback can no longer run against a torn-down view and 
throw.
   
   
   
   ### Fixed issues
   
   <!-- No existing issue; found while auditing component teardown paths. -->
   
   
   ## Details
   
   ### Before: What was the problem?
   
   When `tooltip.showDelay` is greater than `0`, showing a tooltip schedules a 
timer in `TooltipView#_showOrMove`:
   
   ```js
   const delay = tooltipModel.get('showDelay');
   cb = bind(cb, this);
   clearTimeout(this._showTimout);
   delay > 0
       ? (this._showTimout = setTimeout(cb, delay) as any)
       : cb();
   ```
   
   `TooltipView#dispose` never cleared that handle, but it did reset the 
members the callback depends on:
   
   ```js
   this._tooltipContent = null;
   this._tooltipModel = null;
   ```
   
   So if the chart is disposed while a `showDelay` timer is still pending — 
which is the normal case when a user hovers a chart and then the view is 
unmounted (React/Vue route change, tab switch, `echarts.dispose()` before 
re-init) — the callback fires afterwards and dereferences the nulled content:
   
   ```
   TypeError: Cannot read properties of null (reading 'setEnterable')
       at TooltipView._showTooltipContent
       at TooltipView.<anonymous>
   ```
   
   The error surfaces up to `showDelay` milliseconds after the chart is gone, 
so it is reported as a random uncaught exception rather than being traced back 
to `dispose`. It reproduces with both `renderMode: 'html'` and `renderMode: 
'richText'`, and with both `trigger: 'item'` and `trigger: 'axis'`.
   
   Two smaller teardown leaks are in the same area:
   
   - `_refreshUpdateTimeout` is also left pending. Its callback is guarded by 
`!api.isDisposed()` so it does not throw, but the timer keeps the disposed view 
reachable until it fires.
   - `TooltipRichContent#dispose` does not clear its `hideDelay` timer, while 
`TooltipHTMLContent#dispose` already does clear both of its timers.
   
   ### After: How does it behave after the fixing?
   
   `TooltipView#dispose` now clears `_showTimout` and `_refreshUpdateTimeout`, 
and `TooltipRichContent#dispose` clears `_hideTimeout` to match 
`TooltipHTMLContent#dispose`.
   
   The timers are cleared at the very top of `dispose`, before the `env.node || 
!api.getDom()` early return and before the members are nulled, so the cleanup 
cannot be skipped.
   
   Disposing a chart with a pending tooltip timer no longer throws, and no 
tooltip timer outlives the chart.
   
   
   
   ## Document Info
   
   One of the following should be checked.
   
   - [x] This PR doesn't relate to document changes
   - [ ] The document should be updated later
   - [ ] The document changes have been made in apache/echarts-doc#xxx
   
   
   
   ## Misc
   
   ### Security Checking
   
   - [ ] This PR uses security-sensitive Web APIs.
   
   ### ZRender Changes
   
   - [ ] This PR depends on ZRender changes (ecomfe/zrender#xxx).
   
   ### Related test cases or examples to use the new APIs
   
   Added `test/ut/spec/component/tooltip/dispose.test.ts`, covering `showDelay` 
for
   `html`/`richText` render modes and `item`/`axis` triggers, plus the 
`richText`
   `hideDelay` timer. Each case asserts that no tooltip timer is left pending 
after
   `dispose` and that running pending timers does not throw.
   
   Verified that the four `showDelay` cases fail on `master` with
   `TypeError: Cannot read properties of null (reading 'setEnterable')` and 
pass with this change.
   
   `npm run test` (27 suites / 199 tests), `npx tsc --noEmit`, and `eslint` on 
the
   changed files all pass.
   
   ### Merging options
   
   - [x] Please squash the commits into a single one when merging.
   
   ### Other information
   
   While auditing this area I also noticed that `_showTimout` is not cleared in
   `manuallyHideTip`, which is the separate problem reported in #16859 (closed 
as
   stale) and attempted in the unmerged #17499. That is a behavioural change 
rather
   than a teardown fix, so it is intentionally left out of this PR.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to