SupremeTechnopriest / react-idle-timer

User activity timer component
https://idletimer.dev
MIT License
1.15k stars 143 forks source link

Uncaught Error: There is no interval scheduled with the given id "1". #337

Closed jamesga1 closed 1 year ago

jamesga1 commented 1 year ago

Uncaught Error: There is no interval scheduled with the given id "1".

Hello, we've recently added react-idle-timer to replace our existing idle timer, but we're currently logging the following error:

Uncaught Error: There is no interval scheduled with the given id "1". at https://www.ourwebsite/vendor.1ee21d455ed3548a.js: 75, col 864300, Error Object: Error: There is no interval scheduled with the given id "1".

So far it appears to be related to Chrome/Chromium desktop users based on our stack trace, but I'm not sure if it's a browser related issue with workerTimers or something on our end. We haven't been able to recreate the issue with our local dev instances, so any assistance would be appreciated. Please let me know if you need any other information.



export const idleTimerTypes = {
  active: 'active',
  idle: 'idle',
};

  const promptBeforeIdle = timer.sessionPromptBeforeIdle * 60000;
  const timeout = timer.sessionTimeout * 60000;

  const onIdle = () => {
    const requestOptions = {
      method: 'POST',
    };
    fetch(`${timer.apiUrl}/account/delete-auth-cookie`, requestOptions).then(() => {
      setWarningPromptOpen(false);
      setExpiredPromptOpen(true);
      setIsLoggedIn(false);
    });
  };

  const onPrompt = () => {
      setWarningPromptOpen(true);
    };

  const onMessage = (data: PresenceType) => {
    // ensures all tab warning prompts are closed and reactivated.
    if (data.type === idleTimerTypes.active) {
      setWarningPromptOpen(false);
      activate();
    } else if (data.type === idleTimerTypes.idle) {
      handleExpiredDialogClose();
    }
  };

  const { activate, message, start } = useIdleTimer({
    onIdle,
    onPrompt,
    onMessage,
    crossTab: true,
    events: ['keydown', 'mousedown', 'touchstart'],
    leaderElection: true,
    name: 'my-test-idle',
    promptBeforeIdle: promptBeforeIdle,
    syncTimers: 200,
    startOnMount: false,
    startManually: true,
    stopOnIdle: true,
    throttle: 500,
    timeout: timeout,
    timers: workerTimers,
  });`
SupremeTechnopriest commented 1 year ago

IdleTimer doesn't use intervals so I don't think its related. Are you using an interval somewhere in your code?

Your usage of IdleTimer looks ok to me.

fetters5 commented 1 year ago

We think it could be related to the following function https://github.com/SupremeTechnopriest/react-idle-timer/blob/aa4df8af7f376a6f4b594fcb50dbeb1158640428/src/TabManager/LeaderElector.ts#L103

The code throws an error at the line highlighted in the image in our bundle

d3214e6e-fcc5-474e-a0f1-2fbe0e80e581

SupremeTechnopriest commented 1 year ago

Ah you are using leader election. Yeah there are some intervals involved there. Are you un-mounting the component that houses the idle timer hook?

fetters5 commented 1 year ago

We don't unmount, except maybe the explicitly setting the url to an external logout in the function below has a race condition with the broadcast message.


  const handleExpiredDialogClose = () => {
    setExpiredPromptOpen(false);

    // Forces other tabs to also close idle dialog
    message({ type: idleTimerTypes.idle }, false);
    const redirect = window.location.href;
    const url = timer.logoutUrl + '?fromURI=' + redirect;
    window.location.href = url;
  };
SupremeTechnopriest commented 1 year ago

Mmm yeah and I assume that the location of the log out page does not have IdleTimer? I think its a race condition in the unmount logic. I will see if I can protect against throwing the error, but it can be safely ignored. Ill bet if you move idle timer to the root component this would go away.

SupremeTechnopriest commented 1 year ago

This should no longer throw in version 5.6.0. Its the result of a race condition when the hook unmounts.