AggregateException.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / AggregateException.cs / 1305376 / AggregateException.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// 
// AggregateException.cs 
//
// [....] 
//
// Public type to communicate multiple failures to an end-user.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Diagnostics; 
using System.Globalization;
using System.Runtime.Serialization;
using System.Security;
using System.Threading; 

namespace System 
{ 

    /// Represents one or more errors that occur during application execution. 
    /// 
    ///  is used to consolidate multiple failures into a single, throwable
    /// exception object.
    ///  
    [Serializable]
    [DebuggerDisplay("Count = {InnerExceptions.Count}")] 
    public class AggregateException : Exception 
    {
 
        private ReadOnlyCollection m_innerExceptions; // Complete set of exceptions.

        /// 
        /// Initializes a new instance of the  class. 
        /// 
        public AggregateException() 
            : base(Environment.GetResourceString("AggregateException_ctor_DefaultMessage")) 
        {
            m_innerExceptions = new ReadOnlyCollection(new Exception[0]); 
        }

        /// 
        /// Initializes a new instance of the  class with 
        /// a specified error message.
        ///  
        /// The error message that explains the reason for the exception. 
        public AggregateException(string message)
            : base(message) 
        {
            m_innerExceptions = new ReadOnlyCollection(new Exception[0]);
        }
 
        /// 
        /// Initializes a new instance of the  class with a specified error 
        /// message and a reference to the inner exception that is the cause of this exception. 
        /// 
        /// The error message that explains the reason for the exception. 
        /// The exception that is the cause of the current exception.
        /// The  argument
        /// is null.
        public AggregateException(string message, Exception innerException) 
            : base(message, innerException)
        { 
            if (innerException == null) 
            {
                throw new ArgumentNullException("innerException"); 
            }

            m_innerExceptions = new ReadOnlyCollection(new Exception[] { innerException });
        } 

        ///  
        /// Initializes a new instance of the  class with 
        /// references to the inner exceptions that are the cause of this exception.
        ///  
        /// The exceptions that are the cause of the current exception.
        /// The  argument
        /// is null.
        /// An element of  is 
        /// null.
        public AggregateException(IEnumerable innerExceptions) : 
            this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions) 
        {
        } 

        /// 
        /// Initializes a new instance of the  class with
        /// references to the inner exceptions that are the cause of this exception. 
        /// 
        /// The exceptions that are the cause of the current exception. 
        /// The  argument 
        /// is null.
        /// An element of  is 
        /// null.
        public AggregateException(params Exception[] innerExceptions) :
            this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions)
        { 
        }
 
        ///  
        /// Initializes a new instance of the  class with a specified error
        /// message and references to the inner exceptions that are the cause of this exception. 
        /// 
        /// The error message that explains the reason for the exception.
        /// The exceptions that are the cause of the current exception.
        /// The  argument 
        /// is null.
        /// An element of  is 
        /// null. 
        public AggregateException(string message, IEnumerable innerExceptions)
            : this(message, innerExceptions == null ? (List)null : new List(innerExceptions)) 
        {
        }

        ///  
        /// Initializes a new instance of the  class with a specified error
        /// message and references to the inner exceptions that are the cause of this exception. 
        ///  
        /// The error message that explains the reason for the exception.
        /// The exceptions that are the cause of the current exception. 
        /// The  argument
        /// is null.
        /// An element of  is
        /// null. 
        public AggregateException(string message, params Exception[] innerExceptions) :
            this(message, (IList)innerExceptions) 
        { 
        }
 
        /// 
        /// Allocates a new aggregate exception with the specified message and list of inner exceptions.
        /// 
        /// The error message that explains the reason for the exception. 
        /// The exceptions that are the cause of the current exception.
        /// The  argument 
        /// is null. 
        /// An element of  is
        /// null. 
        private AggregateException(string message, IList innerExceptions)
            : base(message, innerExceptions != null && innerExceptions.Count > 0 ? innerExceptions[0] : null)
        {
            if (innerExceptions == null) 
            {
                throw new ArgumentNullException("innerExceptions"); 
            } 

            // Copy exceptions to our internal array and validate them. We must copy them, 
            // because we're going to put them into a ReadOnlyCollection which simply reuses
            // the list passed in to it. We don't want callers subsequently mutating.
            Exception[] exceptionsCopy = new Exception[innerExceptions.Count];
 
            for (int i = 0; i < exceptionsCopy.Length; i++)
            { 
                exceptionsCopy[i] = innerExceptions[i]; 

                if (exceptionsCopy[i] == null) 
                {
                    throw new ArgumentException(Environment.GetResourceString("AggregateException_ctor_InnerExceptionNull"));
                }
            } 

            m_innerExceptions = new ReadOnlyCollection(exceptionsCopy); 
        } 

        ///  
        /// Initializes a new instance of the  class with serialized data.
        /// 
        /// The  that holds
        /// the serialized object data about the exception being thrown. 
        /// The  that
        /// contains contextual information about the source or destination.  
        /// The  argument is null. 
        /// The exception could not be deserialized correctly.
        [SecurityCritical] 
        protected AggregateException(SerializationInfo info, StreamingContext context) :
            base(info, context)
        {
            if (info == null) 
            {
                throw new ArgumentNullException("info"); 
            } 

            Exception[] innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[]; 
            if (innerExceptions == null)
            {
                throw new SerializationException(Environment.GetResourceString("AggregateException_DeserializationFailure"));
            } 

            m_innerExceptions = new ReadOnlyCollection(innerExceptions); 
        } 

        ///  
        /// Sets the  with information about
        /// the exception.
        /// 
        /// The  that holds 
        /// the serialized object data about the exception being thrown.
        /// The  that 
        /// contains contextual information about the source or destination.  
        /// The  argument is null.
        [SecurityCritical] 
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            { 
                throw new ArgumentNullException("info");
            } 
 
            base.GetObjectData(info, context);
 
            Exception[] innerExceptions = new Exception[m_innerExceptions.Count];
            m_innerExceptions.CopyTo(innerExceptions, 0);
            info.AddValue("InnerExceptions", innerExceptions, typeof(Exception[]));
        } 

        ///  
        /// Returns the  that is the root cause of this exception. 
        /// 
        public override Exception GetBaseException() 
        {
            // Returns the first inner AggregateException that contains more or less than one inner exception

            // Recursively traverse the inner exceptions as long as the inner exception of type AggregateException and has only one inner exception 
            Exception back = this;
            AggregateException backAsAggregate = this; 
            while (backAsAggregate != null && backAsAggregate.InnerExceptions.Count == 1) 
            {
                back = back.InnerException; 
                backAsAggregate = back as AggregateException;
            }
            return back;
        } 

        ///  
        /// Gets a read-only collection of the  instances that caused the 
        /// current exception.
        ///  
        public ReadOnlyCollection InnerExceptions
        {
            get { return m_innerExceptions; }
        } 

#if !FEATURE_CORECLR 
        ///  
        /// Invokes a handler on each  contained by this . 
        /// 
        /// The predicate to execute for each exception. The predicate accepts as an
        /// argument the  to be processed and returns a Boolean to indicate
        /// whether the exception was handled. 
        /// 
        /// Each invocation of the  returns true or false to indicate whether the 
        ///  was handled. After all invocations, if any exceptions went 
        /// unhandled, all unhandled exceptions will be put into a new 
        /// which will be thrown. Otherwise, the  method simply returns. If any 
        /// invocations of the  throws an exception, it will halt the processing
        /// of any more exceptions and immediately propagate the thrown exception as-is.
        /// 
        /// An exception contained by this  was not handled.
        /// The  argument is 
        /// null. 
        public void Handle(Func predicate)
        { 
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            } 

            List unhandledExceptions = null; 
            for (int i = 0; i < m_innerExceptions.Count; i++) 
            {
                // If the exception was not handled, lazily allocate a list of unhandled 
                // exceptions (to be rethrown later) and add it.
                if (!predicate(m_innerExceptions[i]))
                {
                    if (unhandledExceptions == null) 
                    {
                        unhandledExceptions = new List(); 
                    } 

                    unhandledExceptions.Add(m_innerExceptions[i]); 
                }
            }

            // If there are unhandled exceptions remaining, throw them. 
            if (unhandledExceptions != null)
            { 
                throw new AggregateException(Message, unhandledExceptions); 
            }
        } 


#endif //!FEATURE_CORECLR
 

 
        ///  
        /// Flattens an  instances into a single, new instance.
        ///  
        /// A new, flattened .
        /// 
        /// If any inner exceptions are themselves instances of
        /// , this method will recursively flatten all of them. The 
        /// inner exceptions returned in the new 
        /// will be the union of all of the the inner exceptions from exception tree rooted at the provided 
        ///  instance. 
        /// 
        public AggregateException Flatten() 
        {
            // Initialize a collection to contain the flattened exceptions.
            List flattenedExceptions = new List();
 
            // Create a list to remember all aggregates to be flattened, this will be accessed like a FIFO queue
            List exceptionsToFlatten = new List(); 
            exceptionsToFlatten.Add(this); 
            int nDequeueIndex = 0;
 
            // Continue removing and recursively flattening exceptions, until there are no more.
            while (exceptionsToFlatten.Count > nDequeueIndex)
            {
                // dequeue one from exceptionsToFlatten 
                IList currentInnerExceptions = exceptionsToFlatten[nDequeueIndex++].InnerExceptions;
 
                for (int i = 0; i < currentInnerExceptions.Count; i++) 
                {
                    Exception currentInnerException = currentInnerExceptions[i]; 

                    if (currentInnerException == null)
                    {
                        continue; 
                    }
 
                    AggregateException currentInnerAsAggregate = currentInnerException as AggregateException; 

                    // If this exception is an aggregate, keep it around for later.  Otherwise, 
                    // simply add it to the list of flattened exceptions to be returned.
                    if (currentInnerAsAggregate != null)
                    {
                        exceptionsToFlatten.Add(currentInnerAsAggregate); 
                    }
                    else 
                    { 
                        flattenedExceptions.Add(currentInnerException);
                    } 
                }
            }

 
            return new AggregateException(Message, flattenedExceptions);
        } 
 
        /// 
        /// Creates and returns a string representation of the current . 
        /// 
        /// A string representation of the current exception.
        public override string ToString()
        { 
            string text = base.ToString();
 
            for (int i = 0; i < m_innerExceptions.Count; i++) 
            {
                text = String.Format( 
                    CultureInfo.InvariantCulture,
                    Environment.GetResourceString("AggregateException_ToString"),
                    text, Environment.NewLine, i, m_innerExceptions[i].ToString(), "<---", Environment.NewLine);
            } 

            return text; 
        } 

    } 

}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK