简体   繁体   中英

Reproducing a Front-end Error

So, I am working on a project as an intern that is using Bugsnag to catch errors in their web application. There is one error that I am trying to fix that I can't reproduce. It is only affecting 2 individuals out of all of our customers using the product. I did not write this code, I am only trying to fix the error in it. The error is TypeError·Uncaught TypeError: Cannot set property 'selected' of undefined and it is in this function on the second line.

function selectInstaller(installer) {
      installers[installer.id].selected = true;
      selectedInstaller[installer.id] = installer;
}

What is suppose to happen is that there is a list of individuals and the user can select an individual to display events on a calendar for that specific individual. Once a user is selected this function is called.

function handleSelectInstaller(event) {
      var $btn = $(this);
      var $li = $btn.closest('li');
      $li.toggleClass('active');
      var installerAttributes = $btn.closest('li').data();
      if($li.hasClass('active')) {
        selectInstaller(installerAttributes);
        fetchInstallerCalendar();
      } else {
        previousInstallerCount = Object.keys(selectedInstaller).length;
        unselectInstaller(installerAttributes);
        syncView();
      }
    }

As you can see the handleSelectInstaller function then calles the selectInstaller funciton, which then the error occurs. Like I said, this is a rare occurance that the error occurs, and I can't see to reproduce the error. I figured that maybe something may be wrong with the database for that specific person, but my manager looked at it and he said it looked right. He also tried logging in to the user's account and trying to reproduce it that way, and it didn't give him any issues (so he couldn't reproduce it on his computer). But Bugsnag is still reporting it when the user is signed in onto their computer. Any ideas on how I can reproduce this error so I can fix the problem? Or could it be completely out of my control?

EDIT : Here is what is called when the page is loaded. The last function will automatically select the user that is logged in. Then when the user(installer) selects or deselects their name, the handleSelectInstaller function is called. The stacktrace is showing us going into the handleSelectInstaller function.

function init(options) {
      var options = options || {};
      baseUrl = serverpath + "v1.0/calendar_events";
      selector = options.selector || '#calendar';
      colors = {
        default: '#59595C',
        disabled: '#ff9f89'
      };
      dateFormat = 'YYYY-MM-DD';
      type = $(selector).data('type');
      installers = {};
      installerArray = [];
      selectedInstaller = {};
      cache = {};
      cacheCalendar = {};
      currentMonth = {start: null, end: null}
      standardInstallerObject = {jobs: {}, daysOfWeekDisabled: {}, time_off: {}, color:null}
      previousInstallerCount = 0;
      setup();
    }

function setup() {
       setupListeners();
       setupDatePickers();
       $('.installer-name').text('Select Installer');
       syncEventTypes();
       syncJobStatuses();
       fetchInstallers(setupCalendar);
     }

function fetchInstallers(callback) {
      $.ajax({
        url: serverpath + 'v1.0/users?role=installers',
        type: "GET",
        dataType: 'json'
      }).done(function(response) {
        loadInstallers(response);
        if(typeof callback === 'function') callback();
      })
      .fail(function(xhr) {
        handleError(xhr);
        $('#calendar-loading-indicator').fadeOut();
      })
      .always(function() { });
    }

    function loadInstallers(response) {
      for(var i in response) {

        var installer = response[i];
        var id = installer.id;
        //need to extend / copy object since the object would be stored by reference not by value
        var copiedObject = $.extend(true, {}, standardInstallerObject);
        var copiedObjectCalendar = $.extend(true, {}, standardInstallerObject);
        cache[id] = copiedObject;
        cacheCalendar[id] = copiedObjectCalendar;
        if(installers[id]) continue;
        installers[id] = installer;
        installerArray.push(installers[id]);
      }

      if(type == 'installer') {
        var installer = installers[$.User.id()];
        selectInstaller(installer);
        $('.installer-pick-list li[data-id="'+ $.User.id() +'"]').addClass('active');
      }
    }

Are you using an ajax call? Maybe mock a long ajax call using setTimeout and see if you get the same error. So wrap the ajax call thats there with a setTimeout call and set it to like 4000 or something like that. Here is a good example of what I am talking about. using SetTimeout with Ajax calls

setTimeout(function(){checkData()}, 5000);
function checkData(){
    $.ajax({ 
        // 
    }); 
}

Since it the load installers function has been ran yet and the user is beating them to it by selecting an installer first you can do something like this.

For the public

$.ajax({
    url: //something
    type: "GET",
    dataType: 'json'
    }).done(function(response) {
        loadInstallers(response);
        $.publish('Installer.set_installer_info');
        if(typeof callback === 'function') callback();
    })
});

For the subscribe

$.subscribe('Installer.set_installer_info', function() {
    $('body').on('click', '.installer-calendar-container .installer-pick-list .selectable', handleSelectInstaller);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM