Forum Discussion

RUDOLF_BOTHMA's avatar
RUDOLF_BOTHMA
Community Hero
6 years ago
Solved

call stack on application exception not returning full stack

Hi all,

 

I'm trying to improve the error handling of my scripting.  Sometimes I have a try/catch in my code to handle some application exceptions e.g. trying to edit a readonly file

 

Current example:

 

function LogError()
{
  try
  {
    LogErrorStack1();
  }
  catch(e)
  {
    LogException(e,"Perhaps you should try that again");
  }
}

function LogErrorStack1()
{
  try   
  {
    LogErrorStack2();
  }
  catch(e)
  {
    throw e;
  }
}

function LogErrorStack2()
{
  try
  {
    throw("test exception");
  }
  catch(e)
  {
    throw e;
  }
}

function LogException(exception, additionalInformation)
{
  Log.Error("An application exception was encountered: \n" + exception,additionalInformation);
  //More work for different exceptions
}

I would expect the call stack to be LogException -> LogError -> LogErrorStack1 -> LogErrorStack2

 

Instead the stack ends at LogError:

 

 

 

It has missed out two of the functions in the call stack. Thoughts on how I can them displayed as well without logging on every tier of the call stack (LogErrorStack1 and LogErrorStack2 catches)?

 

 

 

 

  • That's because the Call Stack is recorded at hte moment that "Log.Error" is called.... and at that point, the only "stack" that is there is the initial LogError call and LogException call.  If you want to see the stack that you are requesting, you should change your code to this so that the Log.Error is at the very bottom of your stack.

    function LogError()
    {
      try
      {
        LogErrorStack1();
      }
      catch(e)
      {
        //Handle Exception
      }
    }
    
    function LogErrorStack1()
    {
      try   
      {
        LogErrorStack2();
      }
      catch(e)
      {
        throw e;
      }
    }
    
    function LogErrorStack2()
    {
      try
      {
        throw("test exception");
      }
      catch(e)
      {
        LogException(e,"Perhaps you should try that again");
      }
    }
    
    function LogException(exception, additionalInformation)
    {
      Log.Error("An application exception was encountered: \n" + exception,additionalInformation);
      //More work for different exceptions
    }

2 Replies

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    That's because the Call Stack is recorded at hte moment that "Log.Error" is called.... and at that point, the only "stack" that is there is the initial LogError call and LogException call.  If you want to see the stack that you are requesting, you should change your code to this so that the Log.Error is at the very bottom of your stack.

    function LogError()
    {
      try
      {
        LogErrorStack1();
      }
      catch(e)
      {
        //Handle Exception
      }
    }
    
    function LogErrorStack1()
    {
      try   
      {
        LogErrorStack2();
      }
      catch(e)
      {
        throw e;
      }
    }
    
    function LogErrorStack2()
    {
      try
      {
        throw("test exception");
      }
      catch(e)
      {
        LogException(e,"Perhaps you should try that again");
      }
    }
    
    function LogException(exception, additionalInformation)
    {
      Log.Error("An application exception was encountered: \n" + exception,additionalInformation);
      //More work for different exceptions
    }
    • RUDOLF_BOTHMA's avatar
      RUDOLF_BOTHMA
      Community Hero

      Two parts to my reply

       

      1. Doh, of course /facepalm

       

      2. This is the correct answer, but I asked entirely the wrong question...

       

      I wan't to be able to have the top level function decide if the exception encountered is serious or not.  Having the call stack in the exception is just a part of the equation if I want to figure out what caused the exception.  This is only required if I consider it to be a serious exception.  This is where my code is at at the moment

       

      function Scriptcall1()
      {
        try
        {
          LogErrorStack1();
        }
        catch(e)
        {
         switch(e)
         {
          case "1":
          Log.Message("This isn't serious, just continue");
          break;
          case "2":
          Log.Error("This is very serious");
          break;
         }
        }
      }
      
      function Scriptcall2()
      {
        try
        {
          LogErrorStack1();
        }
        catch(e)
        {
         switch(e)
         {
          case "1":
          Log.Error("This is very serious this time");
          break;
          case "2":
          Log.Message("This isn't serious this time");
          break;
         }
        }
      }
      
      function LogErrorStack1()
      {
        try   
        {
          LogErrorStack2();
        }
        catch(e)
        {
          throw e;
        }
      }
      
      function LogErrorStack2()
      {
        try
        {
          throw("1");
      // or throw("2"); } catch(e) {
      //***** Here is the actual question I should be asking: ******** LogException(e,"Perhaps you should try that again"); //But I don't want this to error. I want to re-throw the exception to the top level function and let that decide if it's a serious problem throw e; } } function LogException(exception, additionalInformation) { text = " "; parent = LogException.caller; do { fname = parent.toString().match(/function (\w*)/)[1]; text += "at " + fname + "() \r\n"; parent = parent.caller; } while (parent); Log.Message("An application exception was encountered: \n "+ exception + " \n " + Utilities.Trim(text) ,additionalInformation); }

      I'm sort of emulating OO Exception handling where you can catch an exception type and handle that accordingly.  LogException is just a utility function, accessable by all my scripts to display everything nicely, since it will make the log consistent.  I don't know if that's the correct approach though