Exemple #1
0
        /// <summary>
        /// Returns a tracer.
        /// This method is called from the injected bytecode.  Changing the signature of this method will break things.
        /// Calls Finish(returnValue, exceptionObject) on the given tracer object.
        /// If any exception is thrown by the New Relic code, then it is caught and logged.
        /// The injected bytecode doesn't directly call the tracer's finish method
        /// because the .NET 4.0 security model will throw a VerificationException.
        /// </summary>
        /// <param name="tracerObject"></param>
        /// <param name="returnValue"></param>
        /// <param name="exceptionObject"></param>
        public static void FinishTracer(object tracerObject, object returnValue, object exceptionObject)
        {
            try
            {
                // no tracer means no finish call
                if (null == tracerObject)
                {
                    return;
                }

                // validate the tracer we received from the injected code
                ITracer tracer = tracerObject as ITracer;
                if (tracer == null)
                {
                    Log.ErrorFormat("AgentShim.FinishTracer received a tracer object but it was not an ITracer. {0}", tracerObject);
                    return;
                }

                // validate the exception we received from the injected code
                Exception exception = exceptionObject as Exception;
                if (exception == null && exceptionObject != null)
                {
                    Log.ErrorFormat("AgentShim.FinishTracer received an exception object but it was not an Exception. {0}", exceptionObject);
                    return;
                }

                tracer.Finish(returnValue, exception);
            }

            // http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx
            // ThreadAbortException is a special exception that can be caught,
            // but it will automatically be raised again at the end of the catch block.
            // We don't want our Exception handler to catch this exception,
            // since it will throw anyway with a different exception stack.
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception exception)
            {
                try
                {
                    Log.Debug("Exception occurred in AgentShim.FinishTracer", exception);
                }
                catch
                {
                    // if logging fails we have to suck it up and swallow the exception
                }
            }
        }