Forum Discussion

bbi's avatar
bbi
Contributor
9 years ago

How to temporay disconnect a GeneralEvents handler ?

Hello all,

 

Need your help to be sure there is not a better way than mine to achieve my problem.

 

I use GeneralEvents to make a standard wrapper on Log.Message, Log.Warning, Log.Message offering me a way to application-wide bypass some errors and manage multiple same message in log.

 

For example below is the code of the Log.Error wrapper;

/* ---------------------------------------------------------------------------
   Gérer les erreurs répetées via gestion des events
--------------------------------------------------------------------------- */
function GeneralEvents_OnLogError(Sender, LogParams) {
  if (LogParams.MessageText == Globals.LASTERRORLOG) {
    Globals.SAMEERRORCOUNT++;
    LogParams.Locked = true;
  }
  else {
    // Pour éviter un test rouge 
    // - par l'erreur aléatoire de IT_Launch à sa sortie, 
    // - sur une déconnexion de la VM 
    // - ou sur une VM non visible
    // - ou sur la validation d'identification qui n'a pas d'élément
    var skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'exception was encountered while terminating', false, lmNone);
    if (!skip) {
      skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'is invisible', false, lmNone); 
    }
    if (!skip) { 
      skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'because the user session is disconnected', false, lmNone);
    }  
    if (!skip) { 
      skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'process not found', false, lmNone);
    }  
    if (skip) { 
      Log.Message(LogParams.MessageText);
      LogParams.Locked = true;
    }  
    else {	  
      // Transformer les erreurs d'objet inexistants en warning
      if ((Globals.IGNORENOTFOUND) && ((aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'Unable to find the object', false, lmNone)) || (aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'The object does not exist.', false, lmNone)))) {
        Log.Message(LogParams.MessageText, LogParams.AdditionalText, pmHigher, qa.system.logWarning);
        LogParams.Locked = true;
      } 
      else {
        // Gérer les répétitions 		    
        if (Globals.SAMEERRORCOUNT > 1) {
          Log.Message('Erreur "' + Globals.LASTERRORLOG + '" répétée ' + Globals.SAMEERRORCOUNT.toString() + ' fois !', '', pmNormal, qa.system.logInfo);
        }  
      }
      Globals.LASTERRORLOG = LogParams.MessageText;
      var f = GeneralEvents_OnLogError;
      GeneralEvents_OnLogError = null;
      Log.Error(Globals.LASTERRORLOG, LogParams.AdditionalText, pmHighest, qa.system.logError);
      GeneralEvents_OnLogError = f;
      Globals.SAMEERRORCOUNT = 0;
      LogParams.Locked = true;
    }
  }
}

At a certain time i need to really write down a Log.Error (when the error is the first one and it's not a known case to be ignored) but if i fire a Log.Error the event handler is called.

 

Solution is this;

      // Backup the event handler
      var f = GeneralEvents_OnLogError;
      // Remove it
      GeneralEvents_OnLogError = null;
      // Fire the Log.Error
      Log.Error(Globals.LASTERRORLOG, LogParams.AdditionalText, pmHighest, qa.system.logError);
      // Restore the event handler
      GeneralEvents_OnLogError = f;

 

Is there any more efficient/elegant way to do that ?

 

 

  • Bobik's avatar
    Bobik
    Frequent Contributor

    Create a global variable. And then use it to enable\disable your handler's code during playback.

     

     

    var lockErrors= true;
    
    function GeneralEvents_OnLogError(Sender, LogParams) {
      if (!lockErrors)
       return;
      if (LogParams.MessageText == Globals.LASTERRORLOG) {
        Globals.SAMEERRORCOUNT++;
        LogParams.Locked = true;
      }
      else {
        // Pour éviter un test rouge 
        // - par l'erreur aléatoire de IT_Launch à sa sortie, 
        // - sur une déconnexion de la VM 
        // - ou sur une VM non visible
        // - ou sur la validation d'identification qui n'a pas d'élément
        var skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'exception was encountered while terminating', false, lmNone);
        if (!skip) {
          skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'is invisible', false, lmNone); 
        }
        if (!skip) { 
          skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'because the user session is disconnected', false, lmNone);
        }  
        if (!skip) { 
          skip = aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'process not found', false, lmNone);
        }  
        if (skip) { 
          Log.Message(LogParams.MessageText);
          LogParams.Locked = true;
        }  
        else {	  
          // Transformer les erreurs d'objet inexistants en warning
          if ((Globals.IGNORENOTFOUND) && ((aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'Unable to find the object', false, lmNone)) || (aqObject.CompareProperty(LogParams.MessageText, cmpContains, 'The object does not exist.', false, lmNone)))) {
            Log.Message(LogParams.MessageText, LogParams.AdditionalText, pmHigher, qa.system.logWarning);
            LogParams.Locked = true;
          } 
          else {
            // Gérer les répétitions 		    
            if (Globals.SAMEERRORCOUNT > 1) {
              Log.Message('Erreur "' + Globals.LASTERRORLOG + '" répétée ' + Globals.SAMEERRORCOUNT.toString() + ' fois !', '', pmNormal, qa.system.logInfo);
            }  
          }
          Globals.LASTERRORLOG = LogParams.MessageText;
          var f = GeneralEvents_OnLogError;
          GeneralEvents_OnLogError = null;
          Log.Error(Globals.LASTERRORLOG, LogParams.AdditionalText, pmHighest, qa.system.logError);
          GeneralEvents_OnLogError = f;
          Globals.SAMEERRORCOUNT = 0;
          LogParams.Locked = true;
        }
      }
    }

     

     

     

     

    • tristaanogre's avatar
      tristaanogre
      Esteemed Contributor
      I don't typically like global variables that need to be edited in code. But that, essentially, is what you need to do.

      Now, you can probably make it more dynamic as you asked that, in the event handler, you'd call another function that would check the current error with the last error and, if they match, just don't log anything and increment some sort of counter. So, rather than the opening code of if (!lockErrors) return; you would add some additional code before the return to do those little updates and move on. And you would set the lockErrors variable based upon some other code that is executed rather than it being a hard coded value at the top of your unit.
      • bbi's avatar
        bbi
        Contributor

        The algorithm of my event handler is (give it for other people if they can grab ideas):

         

         

         

        Same MessageText than previous message ?
        Yes-> increment repetition counter and lock this Log.Error
        No ->  Check if error message is a known-to-be-ignored one ?
                  Yes-> make a Log.Message instead of a Log.Error and lock this Log.Error
                  No -> Check if repetition message counter is > 0 ?
                            Yes-> as the message has changed then make a unique Log.Message for the repeated message
                        Make a Log.Error entry and reset repetition counter as well as previous message backup and lock this Log.

         

        So after your interesting replies i think i'll keep my solution for now.

         

        The global variable solution works well also but need more lines of code and add external variable.

         

        The splitting method is ok also but add another function. Perhaps it's the more elegant because adding more flexibility but it's the heavier.

         

        Txs for your ideas.