Exceptionless.JavaScript icon indicating copy to clipboard operation
Exceptionless.JavaScript copied to clipboard

Navigating away from the page loses exceptions if the processing queue has not fired

Open jdtaylor91 opened this issue 8 years ago • 13 comments

Using the JavaScript client if an Exception is submitted it isn't sent immediately to Exceptionless, instead it waits for the next 'Processing queue...' event to fire.

While testing this we have observed that if the user navigates away from the current page before the 'Processing queue...' event fires than the exceptions are never logged to Exceptionless. As the 'Processing queue...' event currently fires every 10 seconds it is quite likely that a user would navigate away from a page after an error has occurred. Is there a setting or way to force exceptions to be logged instantly?

jdtaylor91 avatar Oct 05 '16 09:10 jdtaylor91

Having looked at the code i've now used the useLocalStorage setting to use window.localStorage, however this is still not working as expected.

When an error is thrown it is enqueued, i then navigate away from the page before the queue is processed (to another page within my application). On this new page the processing queue is never started meaning the previous error is now setting in localStorage but is not being sent, this is up until a new error occurs at which point all errors in localStorage are picked up.

Is there further configuration required by me to fix this? Or is this a bug and the 'Processing queue...' event should fire regardless of if there has been an error or not?

jdtaylor91 avatar Oct 05 '16 10:10 jdtaylor91

A solution to this could be to update the DefaultEventQueue constructor to start the queue timer straight away, line 1531 of exceptionless.js.

function DefaultEventQueue(config) {
            this._handlers = [];
            this._processingQueue = false;
            this._config = config;
            this.ensureQueueTimer(); /// Add this?
        }

jdtaylor91 avatar Oct 05 '16 10:10 jdtaylor91

we'll I think we should look into firing an event to process the queue when the browser tab changes / on page leave. Ideally it would be nice to be able to sleep the client during this period too. You may not want to fire the queue timer on launch as the config might not be set. What are your thoughts?

niemyjski avatar Oct 05 '16 19:10 niemyjski

Having it respond to browser tab change or page leave would be great, the 'unload' event could be used here to prompt the queue to process one last time, however it looks like the actions that cause this event to fire can differ between browsers (i.e. - some versions of Firefox don't trigger the event when the window is closed), if this sort of change was made it would have to be heavily cross-browser tested.

I still feel that the processing queue should be started on page load to allow any exceptions stored within localStorage to be sent, perhaps instead of within the constructor the processing queue should be started when the config has been loaded in the 'getSettings' or 'updateSettings' methods?

The root of the issue is down to the queue only being processed once every 10 seconds, is this something that could be called more often? Looking at the code very little processing is done if there is nothing waiting in the queue so i doubt this running more frequently would cause any performance issues.

jdtaylor91 avatar Oct 05 '16 20:10 jdtaylor91

I was talking to @srijken about wiring up to the onbeforeunload and unload events and calling processqueue but ensure it does a sync send (http://stackoverflow.com/questions/4945932/window-onbeforeunload-ajax-request-problem-with-chrome). This should help with this. Also we need to investigate and see if window.onload if the app is fully configured at this stage. if it is we could process the queue (if there are any items).

The problem with just calling it when the client is loading up is you can block other apps from making requests as well as the fact you may want to configure the client (thus you can't just fire it off from the constructor as it's hit when the object is created).

niemyjski avatar Oct 05 '16 21:10 niemyjski

There is a fine line here on startup costs, we need to come to a consensus on whats appropriate. Should we look into events that are cross browser and fire when page is idle (we trigger it after the page is all updated and idle)?

niemyjski avatar Oct 05 '16 21:10 niemyjski

@jdtaylor91 would you mind looking into how we could accomplish processing the queue on startup.

niemyjski avatar Oct 05 '16 21:10 niemyjski

@niemyjski I've had a quick look and believe the simplest solution would be to start the processing queue after the config has been loaded, this would avoid the issue of it starting straight away and would allow any configuration changes to take effect.

On a side note, would it be possible to add a new setting to allow us to specify if we want to use the processing queue or not? By default it could be set to true so that the queue can be used, but when set to false it would result in the error being logged to exceptionless as soon as it is submitted.

jdtaylor91 avatar Oct 07 '16 06:10 jdtaylor91

I think the first is acceptable and also look into looking into the unload and unloading events.

If anything I think that a proposal to pause the queue and start queue processing could be a separate issue. It might be nice to have something like that so everything is suspended while a tab / js app sleeps.

niemyjski avatar Oct 07 '16 22:10 niemyjski

We should also implement this (for browsers that support it, which is just chrome at the moment): https://wicg.github.io/BackgroundSync/spec/

srijken avatar Oct 13 '16 10:10 srijken

Yeah, that might be good, we'd have to check for the existence of fetch and that api. I wonder if there is a legacy way to do sync xhr.

niemyjski avatar Oct 13 '16 13:10 niemyjski

Has there been any progress on this?

bmdixon avatar Nov 23 '17 13:11 bmdixon

So by default we now use local storage so events are always persisted. However I haven’t found any event that fires when you navigate away (I sis haven’t really looked in a long while) sovthe wueue won’t be processed until next visit. Can you please look into seeing if there is an event that covers this scenario that we can wire up to?

niemyjski avatar Nov 23 '17 15:11 niemyjski

We handle this much better in the 2.0 client. We automatically use local storage and we listen to browser events for unloading and we call process queue. Please let us know how this is working out for you.

niemyjski avatar Feb 21 '23 13:02 niemyjski