-
Notifications
You must be signed in to change notification settings - Fork 6.7k
tooltip race condition. throws TypeError: Cannot read property 'css' of null #4757
Comments
@RobJacobs thoughts on this? Seems a bit fishy that this can even occur looking at the code, but I was able to reproduce this in the Plunker (with a lot of trouble). |
I reproduced it too. I know the feel because this kind of libraries are really prompted to race conditions. |
@brenovieira @wesleycho Here is a plunk with a proposed fix - move the calls to cancelShow() and cancelHide() to the removeTooltip() function. Seems to fix the problem, if there are no objections to this approach I will create a PR. |
@RobJacobs , it seems to fix the issue. But on
Now,
Adding Also in
What do you think ? |
@brenovieira Don't confuse scope with the internal tooltip scope (tooltipLinkedScope). The scope.$on('$destroy is a fail safe cleanup that is called when the element that has the tooltip directive on it is destroyed. The tooltipLinkedScope is manually destroyed in removeTooltip(), scope.$on('$destroy' is not called when the tooltip hides. scope.$on('$destroy does not call unregisterObservers() directly, it relies on that happening in the removeTooltip() function. It does however call unregisterTriggers(), perhaps you confused the 2? The removeTooltip no longer needs to set the transitionTimeout to null as that will be done in the cancelHide(), I will remove that line. Since the removeTooltip() now calls the cancelShow() and cancelHide(), they are no longer necessary in the scope.$on('$destroy'. I will remove those lines. So now we end up with:
Typically we go through this sort of code analysis when we create the PR and can comment on the actual PR by line but I wanted to give you a chance to verify the proposed change fixed the issue you reported. So I'll go ahead and make a PR and we can continue the discussion there, thanks. |
Yeah, I'm not confusing it, I was just analizing the changes, but indeed we can discuss this on the PR.
That's true. My bad.
Great. |
I got the same error in my project in "angular-bootstrap": "0.14.3" but my case is a bit different. I have a custom dropdown directive which has tooltip assigned through a function:
If I use navigation key to go down through all items fast, tooltip is updated in rapid succession, maybe faster than it can deal with because if I hold down the key, navigation slows down and at one point I start getting errors:
|
@progmars This fix is not in the 0.14.3 release. Do you still get the error when using the latest from the master branch? |
I'm using bower version from https://github.com/angular-ui/bootstrap-bower , so it is tricky to upgrade tooltip to master because bower version has two large concatenated bootstrap files which cannot be found in this GitHub repository. I guess, I'll have to wait when bower repository will be updated. |
@progmars, you can build |
Tooltip directive has a race condition on this line and this line.
If you have two tooltips and hover from one element to another a few times you will see the error.
I've created this plunker.
And attached these two screenshots to show you the error:
I tested with tooltip and tooltip-html and both have the same issue.
You're checking tooltip is null or undefined and setting a timeout, but if before the timeout triggers,
removeTooltip()
is called, you settooltip = null;
here and the exception occurs after timeout triggers.It doesn't break the ui, but I've setted
$exceptionhandler
in my app to send me an email with the error, and I'm getting this error a lot (like 50 times yesterday), so I think it happens quite frequently in a normal use case with "common users".A "double-checked locking" would solve the error, I mean, just check
if (!tooltip || !tooltip.html()) { return; }
again inside the timeout, before set position.If you agree, I can open a PR with this.
The text was updated successfully, but these errors were encountered: