public static int HandleException(Exception e) { //TargetInvocationException is almost always the outer //since we call the variation through late binding if (e.InnerException != null) { e = e.InnerException; } int eResult = TEST_FAIL; object actual = e.GetType(); object expected = null; string message = e.Message; tagERRORLEVEL eErrorLevel = tagERRORLEVEL.HR_FAIL; //Log the exception back to LTM (or whatever has the console) if (e is CTestException) { CTestException eTest = (CTestException)e; //Setup more meaningful info actual = eTest.Actual; expected = eTest.Expected; eResult = eTest.Result; switch (eResult) { case TEST_PASS: case TEST_SKIPPED: Console.WriteLine(e.Message); return(eResult); //were done case TEST_WARNING: eErrorLevel = tagERRORLEVEL.HR_WARNING; break; } ; } //Note: We don't use Exception.ToString as the details for the log since that also includes //the message text (again). Normally this isn't a problem but if you throw a good message //(multiple lines) it show up twice and is confusing. So we will strictly use the //StackTrace as the details and roll our own message (which also include inner exception //messages). Exception inner = e.InnerException; CError.Log(actual, expected, e.Source, message, e.StackTrace, eErrorLevel); while (inner != null) { CError.WriteLine("\n INNER EXCEPTION :"); CError.Log(actual, expected, inner.Source, inner.Message, inner.StackTrace, eErrorLevel); inner = inner.InnerException; } return(eResult); }