diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fs
new file mode 100644
index 00000000000..aed5876bf0d
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fs
@@ -0,0 +1,58 @@
+//
+open System
+open System.IO
+open System.Threading.Tasks
+
+let getAllFiles str =
+ // Should throw an UnauthorizedAccessException exception.
+ System.IO.Directory.GetFiles(str, "*.txt", System.IO.SearchOption.AllDirectories)
+
+// Get a folder path whose directories should throw an UnauthorizedAccessException.
+let path =
+ let directory =
+ Environment.SpecialFolder.UserProfile
+ |> Environment.GetFolderPath
+ |> Directory.GetParent
+ directory.FullName
+
+// Use this line to throw an exception that is not handled.
+// let task1 = Task.Factory.StartNew(fun () -> raise (IndexOutOfRangeException()) )
+let task1 = Task.Factory.StartNew(fun () -> getAllFiles (path))
+
+let execute () =
+ try
+ task1.Wait()
+ with
+ | :? UnauthorizedAccessException -> printfn "Caught unauthorized access exception-await behavior"
+ | :? AggregateException as ae ->
+ printfn "Caught aggregate exception-Task.Wait behavior"
+
+ ae.Handle (fun x ->
+ match x with
+ | :? UnauthorizedAccessException ->
+ printfn "You do not have permission to access all folders in this path."
+ printfn "See your network administrator or try another path."
+ true
+ | _ -> false)
+ printfn $"""task1 Status: {if task1.IsCompleted then "Completed," else ""}{task1.Status}"""
+
+execute ()
+
+// The example displays the following output if the file access task is run:
+// You do not have permission to access all folders in this path.
+// See your network administrator or try another path.
+// task1 Status: Completed,Faulted
+// It displays the following output if the second task is run:
+// Unhandled exception. System.AggregateException: One or more errors occurred. (Index was outside the bounds of the array.) (Index was outside the bounds of the array.)
+// ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
+// at Exception1.task1@19.Invoke()
+// at System.Threading.Tasks.Task`1.InnerInvoke()
+// at System.Threading.Tasks.Task.<>c.<.cctor>b__277_0(Object obj)
+// at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
+// --- End of stack trace from previous location ---
+// at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
+// at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
+// --- End of inner exception stack trace ---
+// at System.AggregateException.Handle(Func`2 predicate)
+// at .$Exception1.main@()
+//
diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fsproj b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fsproj
new file mode 100644
index 00000000000..489dceab6c8
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fsproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
+
diff --git a/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/flatten2.fs b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/flatten2.fs
new file mode 100644
index 00000000000..394e25abd32
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/flatten2.fs
@@ -0,0 +1,38 @@
+module flatten2
+//
+open System
+open System.Threading.Tasks
+
+type CustomException(message) =
+ inherit Exception(message)
+
+let task1 =
+ Task.Factory.StartNew (fun () ->
+ let child1 =
+ Task.Factory.StartNew(
+ (fun () ->
+ let child2 =
+ Task.Factory.StartNew(
+ (fun () -> raise (CustomException "Attached child2 faulted,")),
+ TaskCreationOptions.AttachedToParent
+ )
+ raise (CustomException "Attached child1 faulted.")),
+ TaskCreationOptions.AttachedToParent
+ )
+ ()
+ )
+
+try
+ task1.Wait()
+with
+| :? AggregateException as ae ->
+ for e in ae.Flatten().InnerExceptions do
+ if e :? CustomException then
+ printfn "%s" e.Message
+ else
+ reraise()
+
+// The example displays the following output:
+// Attached child1 faulted.
+// Attached child2 faulted.
+//
diff --git a/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/handlemethod2.fs b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/handlemethod2.fs
new file mode 100644
index 00000000000..c879e554195
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/handlemethod2.fs
@@ -0,0 +1,26 @@
+module handlemethod2
+//
+open System
+open System.Threading.Tasks
+
+type CustomException(message) =
+ inherit Exception(message)
+
+let task1 =
+ Task.Run(fun () -> raise (CustomException "This exception is expected!"))
+
+try
+ task1.Wait()
+with
+| :? AggregateException as ae ->
+ // Call the Handle method to handle the custom exception,
+ // otherwise rethrow the exception.
+ ae.Handle (fun ex ->
+ if ex :? CustomException then
+ printfn $"{ex.Message}"
+
+ ex :? CustomException)
+
+// The example displays the following output:
+// This exception is expected!
+//
diff --git a/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions.fs b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions.fs
new file mode 100644
index 00000000000..b69a636c397
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions.fs
@@ -0,0 +1,53 @@
+module taskexceptions
+//
+open System
+open System.IO
+open System.Threading.Tasks
+
+let getAllFiles path =
+ let task1 =
+ Task.Run(fun () -> Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories))
+
+ try
+ task1.Result
+ with
+ | :? AggregateException as ae ->
+ ae.Handle (fun x ->
+ // Handle an UnauthorizedAccessException
+ if x :? UnauthorizedAccessException then
+ printfn "You do not have permission to access all folders in this path."
+ printfn "See your network administrator or try another path."
+
+ x :? UnauthorizedAccessException)
+
+ Array.empty
+
+// This should throw an UnauthorizedAccessException.
+try
+ let files = getAllFiles @"C:\"
+
+ if not (isNull files) then
+ for file in files do
+ printfn $"{file}"
+with
+| :? AggregateException as ae ->
+ for ex in ae.InnerExceptions do
+ printfn $"{ex.GetType().Name}: {ex.Message}"
+
+printfn ""
+
+// This should throw an ArgumentException.
+try
+ for s in getAllFiles "" do
+ printfn $"{s}"
+with
+| :? AggregateException as ae ->
+ for ex in ae.InnerExceptions do
+ printfn $"{ex.GetType().Name}: {ex.Message}"
+
+// The example displays the following output:
+// You do not have permission to access all folders in this path.
+// See your network administrator or try another path.
+//
+// ArgumentException: The path is empty. (Parameter 'path')
+//
diff --git a/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions2.fs b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions2.fs
new file mode 100644
index 00000000000..92d8034a6d7
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions2.fs
@@ -0,0 +1,43 @@
+module taskexceptions2
+//
+open System
+open System.IO
+open System.Threading.Tasks
+
+let executeTasks () =
+ // Assume this is a user-entered String.
+ let path = @"C:\"
+
+ let tasks =
+ [| Task.Run (fun () ->
+ // This should throw an UnauthorizedAccessException.
+ Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories))
+ :> Task
+ Task.Run (fun () ->
+ if path = @"C:\" then
+ raise (ArgumentException "The system root is not a valid path.")
+
+ [| ".txt"; ".dll"; ".exe"; ".bin"; ".dat" |])
+ :> Task
+ Task.Run(fun () -> raise (NotImplementedException "This operation has not been implemented")) |]
+
+ try
+ Task.WaitAll(tasks)
+ with
+ | :? AggregateException as ae -> raise (ae.Flatten())
+
+try
+ executeTasks ()
+with
+| :? AggregateException as ae ->
+ for e in ae.InnerExceptions do
+ printfn $"{e.GetType().Name}:\n {e.Message}"
+
+// The example displays the following output:
+// UnauthorizedAccessException:
+// Access to the path 'C:\Documents and Settings' is denied.
+// ArgumentException:
+// The system root is not a valid path.
+// NotImplementedException:
+// This operation has not been implemented.
+//
diff --git a/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/tpl_exceptions.fsproj b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/tpl_exceptions.fsproj
new file mode 100644
index 00000000000..01c77cf1e9a
--- /dev/null
+++ b/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/tpl_exceptions.fsproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
+
+
+
+
diff --git a/xml/System/AggregateException.xml b/xml/System/AggregateException.xml
index f0de8893cbe..21895053bef 100644
--- a/xml/System/AggregateException.xml
+++ b/xml/System/AggregateException.xml
@@ -71,6 +71,7 @@
The following example catches the exception and calls the method to handle each exception it contains. Compiling and running the example with the first `task1` variable should result in an object that contains an exception. Commenting out that line, uncommenting the second `task1` variable, and compiling and running the example produces an object that contains an exception.
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.aggregateexception.class/cs/exception1.cs" id="Snippet1":::
+ :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.aggregateexception.class/fs/exception1.fs" id="Snippet1":::
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.aggregateexception.class/vb/exception1.vb" id="Snippet1":::
]]>
@@ -548,11 +549,13 @@
In the following example, nested instances are flattened and handled in just one loop.
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_Misc/tpl_exceptions/cs/flatten2.cs" id="Snippet22":::
+ :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/flatten2.fs" id="Snippet22":::
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_Misc/tpl_exceptions/vb/flatten2.vb" id="Snippet22":::
You can also use the method to rethrow the inner exceptions from multiple instances thrown by multiple tasks in a single instance, as the following example shows.
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_Misc/tpl_exceptions/cs/taskexceptions2.cs" id="Snippet13":::
+ :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions2.fs" id="Snippet13":::
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_Misc/tpl_exceptions/vb/taskexceptions2.vb" id="Snippet13":::
]]>
@@ -712,11 +715,13 @@
Ordinarily, an exception handler that catches an exception uses a `foreach` loop (in C#) or `For Each` loop (in Visual Basic) to handle each exception in its collection. Instead, the following example uses the method to handle each exception, and only re-throws exceptions that are not `CustomException` instances.
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_Misc/tpl_exceptions/cs/handlemethod2.cs" id="Snippet16":::
+ :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/handlemethod2.fs" id="Snippet16":::
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_Misc/tpl_exceptions/vb/handlemethod2.vb" id="Snippet16":::
The following is a more complete example that uses the method to provide special handling for an when enumerating files.
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_Misc/tpl_exceptions/cs/taskexceptions.cs" id="Snippet12":::
+ :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_Misc/tpl_exceptions/fs/taskexceptions.fs" id="Snippet12":::
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_Misc/tpl_exceptions/vb/taskexceptions.vb" id="Snippet12":::
]]>