Forum Discussion

ryank's avatar
ryank
Occasional Contributor
9 years ago

Cross-Unit JScript Exceptions

I read in the SmartBear documentation here: Handling Exceptions in Scripts that TestComplete handles cross-unit exceptions in JScript except in certain cases. I followed another link to JScript Specifics and found that TestComplete cannot handle script exceptions thrown from a method of an object created in another Script Unit. I have the following case which does not meet that criteria but still isn't working:

 

Unit A

//USEUNIT UnitB

function main(){
  doSomething(function(){
    throw new Error("Test");
  });
}

Unit B

function doSomething(func){
    try{
      func.apply(null,[]);
    }catch(e){
      Log.Message(e.description)    
    }
}

Since that does not fall under the category mentioned, it seems like this kind of thing should work. I get that it's kind of a weird construct. But it would be handy in our project if this kind of thing could work properly. Does anyone know in which cases cross-unit exceptions can be caught properly?

6 Replies

  • Well, this is still part the same kind of problem:  You are defining an anonymous function in UnitA and trying to call it from UnitB (func.apply).  You can see this if you try defining similar anonymous functions in the two units:

     

     

    // UnitA:
    function anonA() { throw new Error("anonA"); }
    
    // UnitB:
    function anonB() { throw new Error("anonB"); }

     

     

    and then call them from main

     

    function main()
    {
      doSomething(anonB);
      doSomething(anonA);
    }

     

    Edit:

    To finish the thought...  the exception handling for anonB() works because the function is defined in UnitB and you're calling it from UnitB.  The exception handling for anonA() fails because the function is defined in UnitA and you're calling it from unitB  . . . the exception handling crosses unit boundaries.

     

    • chrisb's avatar
      chrisb
      Regular Contributor

      Deleted my response, SmartBear support gave the answer above!

    • ryank's avatar
      ryank
      Occasional Contributor

      To continue this though, it seems like sometimes exception handling will work across multiple units for instance, if I did the following:

       

      Unit A:

      //USEUNIT UnitB
      
      function main(){
        try{
          doSomething();
        }catch(e){
          Log.Message(e.description)
        }
      }

      Unit B:

      function doSomething(func){
          throw new Error("Test");
      }

      The error is caught properly again. The exception is thrown across the script unit boundary but still gets caught. So I was wondering what exactly gets caught between scripts and what does not

      • joseph_michaud's avatar
        joseph_michaud
        Moderator

        Ah! I remember now... I had worked a case previously.  The issue seems to be that we can handle exception propagation with direct calls to remote functions but not through copies or references.  So while this would work:

         

        //USEUNIT UnitB
        function main()
        {
          try {
            doSomething();  // This is direct
          } catch(e) {
            Log.Message(e.message);
          }
        }

         

        this would not:

         

        //USEUNIT UnitB
        function main()
        {
          try {
            var fn = doSomething;  // indirect
            fn();  // Microsoft JScript runtime error
          } catch(e) {
            Log.Message(e.message);
          }
        }

         

        The only workaround I could come up with at the time was to make the call to the remote function in a try/catch from within the remote unit (assuming you know where it is...) and provide callbacks to the handle the catching code.

         

         

        //USEUNIT UnitB
        function main()
        {
          var fn = doSomething;
          remotecall( fn, catchfunc );  // call the function from its own unit
        }
        
        function catchfunc(e) { Log.Message(e.description); }
        
        
        //UnitB
        function remotecall( fn, catchfunc )
        {
          try {
            fn();
          } catch(e) {
            catchfunc();
          }
        }
        
        function doSomething()
        {
          throw new Error("doSomething");
        }

         

        Not a pretty hack.

         

        I urge you to submit a feature request or add your vote to any existing feature request to see if the developers can get this fixed.

         

  • chrisb's avatar
    chrisb
    Regular Contributor

    My hunch is that this is do with Javascript scope.

     

    Put your test script (Unit A) in a try catch block and it works fine.

     

    //USEUNIT UnitB
    
    function main() {
        doSomething(function() {
            try {
                throw new Error("Test");
    
            } catch (e) {
                Log.Message(e.description);
            }
        });
    }

     

     

     

     

    • ryank's avatar
      ryank
      Occasional Contributor

      Possibly. What exactly do you mean by a scoping thing though? For instance, if I put the original code for doSomething() in UnitA, the Exception handling works properly.

       

      Unfortunately, this kind of external exception catching is necessary to what we're trying to create. We're looking to create a "try" concept for TestComplete Errors. We have that part working so that you can pass a function and any TC logged errors will be deffered to warnings (and then accessed in a "catch" function) but unfortunately, it does not work with JS exceptions since they cannot currently be caught in the way I showed. They also are not handled as normal TC Errors which makes things trickier.