Add a third AOT location, alongside ~/.mono/aot-cache and the assembly dir
[mono.git] / mcs / class / corlib / System / AggregateException.cs
1 //
2 // AggregateException.cs
3 //
4 // Authors:
5 //   Marek Safar (marek.safar@gmail.com)
6 //
7 // Copyright (c) 2008 Jérémie "Garuma" Laval
8 // Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 //
29
30 #if NET_4_0
31 using System;
32 using System.Collections.ObjectModel;
33 using System.Collections.Generic;
34 using System.Runtime.Serialization;
35
36 namespace System
37 {
38         [System.SerializableAttribute]
39         [System.Diagnostics.DebuggerDisplay ("Count = {InnerExceptions.Count}")]
40         public class AggregateException : Exception
41         {
42                 List<Exception> innerExceptions = new List<Exception> ();
43                 const string defaultMessage = "One or more errors occurred";
44                 
45                 public AggregateException () : base (defaultMessage)
46                 {
47                 }
48                 
49                 public AggregateException (string message): base (message)
50                 {
51                 }
52                 
53                 public AggregateException (string message, Exception innerException): base (message, innerException)
54                 {
55                         if (innerException == null)
56                                 throw new ArgumentNullException ("innerException");
57                         innerExceptions.Add (innerException);
58                 }
59                 
60                 protected AggregateException (SerializationInfo info, StreamingContext context)
61                         : base (info, context)
62                 {
63                 }
64                 
65                 public AggregateException (params Exception[] innerExceptions)
66                         : this (defaultMessage, innerExceptions)
67                 {
68                 }
69                 
70                 public AggregateException (string message, params Exception[] innerExceptions)
71                         : base (message, innerExceptions == null || innerExceptions.Length == 0 ? null : innerExceptions[0])
72                 {
73                         if (innerExceptions == null)
74                                 throw new ArgumentNullException ("innerExceptions");
75                         foreach (var exception in innerExceptions)
76                                 if (exception == null)
77                                         throw new ArgumentException ("One of the inner exception is null", "innerExceptions");
78
79                         this.innerExceptions.AddRange (innerExceptions);
80                 }
81                 
82                 public AggregateException (IEnumerable<Exception> innerExceptions)
83                         : this (defaultMessage, innerExceptions)
84                 {
85                 }
86                 
87                 public AggregateException (string message, IEnumerable<Exception> innerExceptions)
88                         : this (message, new List<Exception> (innerExceptions).ToArray ())
89                 {
90                 }
91                 
92                 public AggregateException Flatten ()
93                 {
94                         List<Exception> inner = new List<Exception> ();
95                         
96                         foreach (Exception e in innerExceptions) {
97                                 AggregateException aggEx = e as AggregateException;
98                                 if (aggEx != null) {
99                                         inner.AddRange (aggEx.Flatten ().InnerExceptions);
100                                 } else {
101                                         inner.Add (e);
102                                 }                               
103                         }
104
105                         return new AggregateException (inner);
106                 }
107                 
108                 public void Handle (Func<Exception, bool> predicate)
109                 {
110                         if (predicate == null)
111                                 throw new ArgumentNullException ("predicate");
112
113                         List<Exception> failed = new List<Exception> ();
114                         foreach (var e in innerExceptions) {
115                                 if (!predicate (e))
116                                         failed.Add (e);
117                         }
118
119                         if (failed.Count > 0)
120                                 throw new AggregateException (failed);
121                 }
122                 
123                 public ReadOnlyCollection<Exception> InnerExceptions {
124                         get {
125                                 return innerExceptions.AsReadOnly ();
126                         }
127                 }
128
129                 internal void AddChildException (AggregateException childEx)
130                 {
131                         if (innerExceptions == null)
132                                 innerExceptions = new List<Exception> ();
133                         if (childEx == null)
134                                 return;
135
136                         innerExceptions.Add (childEx);
137                 }
138                 
139                 public override string ToString ()
140                 {
141                         System.Text.StringBuilder finalMessage = new System.Text.StringBuilder (base.ToString ());
142
143                         int currentIndex = -1;
144                         foreach (Exception e in innerExceptions) {
145                                 finalMessage.Append (Environment.NewLine);
146                                 finalMessage.Append (" --> (Inner exception ");
147                                 finalMessage.Append (++currentIndex);
148                                 finalMessage.Append (") ");
149                                 finalMessage.Append (e.ToString ());
150                                 finalMessage.Append (Environment.NewLine);
151                         }
152                         return finalMessage.ToString ();
153                 }
154
155                 public override void GetObjectData (SerializationInfo info,     StreamingContext context)
156                 {
157                         if (info == null) {
158                                 throw new ArgumentNullException("info");
159                         }
160                         base.GetObjectData(info, context);
161                         info.AddValue ("InnerExceptions", innerExceptions.ToArray(), typeof (Exception[]));
162                 }
163
164                 public override Exception GetBaseException ()
165                 {
166                         Exception inner = this;
167                         for (var ae = this; ae.innerExceptions.Count == 1;) {
168                                 inner = ae.InnerExceptions [0];
169
170                                 var aei = inner as AggregateException;
171                                 if (aei == null)
172                                         break;
173
174                                 ae = aei;
175                         }
176
177                         return inner;
178                 }
179         }
180 }
181 #endif