Thanks to visit codestin.com
Credit goes to github.com

Skip to content

System.AggregateException F# snippets #7407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// <Snippet1>
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<string []>.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 [email protected]()
// 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 <StartupCode$exception1>.$Exception1.main@()
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="exception1.fs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module flatten2
// <Snippet22>
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.
// </Snippet22>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module handlemethod2
// <Snippet16>
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!
// </Snippet16>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module taskexceptions
// <snippet12>
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')
// </snippet12>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module taskexceptions2
// <snippet13>
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.
// </Snippet13>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="flatten2.fs" />
<Compile Include="taskexceptions2.fs" />
<Compile Include="handlemethod2.fs" />
<Compile Include="taskexceptions.fs" />
</ItemGroup>

</Project>
5 changes: 5 additions & 0 deletions xml/System/AggregateException.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
The following example catches the <xref:System.AggregateException> exception and calls the <xref:System.AggregateException.Handle%2A> method to handle each exception it contains. Compiling and running the example with the first `task1` variable should result in an <xref:System.AggregateException> object that contains an <xref:System.UnauthorizedAccessException> exception. Commenting out that line, uncommenting the second `task1` variable, and compiling and running the example produces an <xref:System.AggregateException> object that contains an <xref:System.IndexOutOfRangeException> 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":::

]]></format>
Expand Down Expand Up @@ -548,11 +549,13 @@
In the following example, nested <xref:System.AggregateException> 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 <xref:System.AggregateException.Flatten%2A?displayProperty=nameWithType> method to rethrow the inner exceptions from multiple <xref:System.AggregateException> instances thrown by multiple tasks in a single <xref:System.AggregateException> 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":::

]]></format>
Expand Down Expand Up @@ -712,11 +715,13 @@
Ordinarily, an exception handler that catches an <xref:System.AggregateException> exception uses a `foreach` loop (in C#) or `For Each` loop (in Visual Basic) to handle each exception in its <xref:System.AggregateException.InnerExceptions%2A> collection. Instead, the following example uses the <xref:System.AggregateException.Handle%2A> 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 <xref:System.AggregateException.Handle%2A> method to provide special handling for an <xref:System.UnauthorizedAccessException> 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":::

]]></format>
Expand Down