![]() |
VOOZH | about |
dotnet add package AElf.ExceptionHandler --version 1.8.2
NuGet\Install-Package AElf.ExceptionHandler -Version 1.8.2
<PackageReference Include="AElf.ExceptionHandler" Version="1.8.2" />
<PackageVersion Include="AElf.ExceptionHandler" Version="1.8.2" />Directory.Packages.props
<PackageReference Include="AElf.ExceptionHandler" />Project file
paket add AElf.ExceptionHandler --version 1.8.2
#r "nuget: AElf.ExceptionHandler, 1.8.2"
#:package AElf.ExceptionHandler@1.8.2
#addin nuget:?package=AElf.ExceptionHandler&version=1.8.2Install as a Cake Addin
#tool nuget:?package=AElf.ExceptionHandler&version=1.8.2Install as a Cake Tool
A demo of AOP Exception Handling.
This is a C# class named ExceptionHandler which is an aspect designed to handle exceptions in methods through PostSharp's OnMethodBoundaryAspect. It intercepts methods when they throw an exception and allows for custom exception handling logic. The code leverages aspects to capture method execution and provides a strategy to deal with specific types of exceptions.
Inheritance from OnMethodBoundaryAspect of PostSharp:
The ExceptionHandler class extends OnMethodBoundaryAspect, which allows intercepting the method execution at predefined points, specifically when exceptions are thrown (OnException method).
Attributes and Fields:
Pros:
Cons:
FlowBehavior:
Create a method in your target class that handles exceptions and returns a Task<ExceptionHandlingStrategy>. The strategy will dictate how the flow of the program should behave (e.g., return, rethrow, throw).public class ExceptionHandlingService
{
public static async Task<FlowBehavior> HandleException(Exception ex, int i)
{
Console.WriteLine($"Handled exception: {ex.Message}");
await Task.Delay(100);
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = true
}
}
}
[ExceptionHandler(typeof(ArgumentNullException), TargetType = typeof(ExceptionHandlingService), MethodName = nameof(ExceptionHandlingService.HandleException))]
protected virtual Task SomeMethod(int i)
{
// Business logic that may throw exceptions
}
All methods with the ExceptionHandler attribute have 2 requirements:
There are 3 ways to return the exception through the Flow Behavior:
public async Task<FlowBehavior> HandleException(Exception ex, string message)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = true
}
}
public async Task<FlowBehavior> HandleException(Exception ex, string message)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Rethrow
}
}
public async Task<FlowBehavior> HandleException(Exception ex, string message)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Throw,
ReturnValue = new Exception("New Exception")
}
}
public async Task<FlowBehavior> HandleException(Exception ex, string message)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Continue
}
}
You can stack multiple ExceptionHandler attributes on a method to handle multiple exceptions.
[ExceptionHandler([typeof(InvalidOperationException), typeof(ArgumentException)], TargetType = typeof(BookAppService), MethodName = nameof(HandleSpecificException))]
[ExceptionHandler(typeof(Exception), TargetType = typeof(BookAppService), MethodName = nameof(HandleException))]
public async Task<BookDto> CreateAsync(CreateBookInput input)
{
// Business logic that may throw exceptions
}
From the example above, the method CreateAsync will handle InvalidOperationException and ArgumentException with the HandleSpecificException method and handle any other exceptions with the HandleException method.
Signature of the callback method can be either of the following:
public async Task<FlowBehavior> HandleSpecificException(Exception ex, CreateBookInput message)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = new BookDto()
};
}
public async Task<FlowBehavior> HandleException(Exception ex)
{
return new FlowBehavior
{
ExceptionHandlingStrategy = ExceptionHandlingStrategy.Return,
ReturnValue = new BookDto()
};
}
The Finally method is called after the method execution is completed. The method signature should follow the same signature as the method that an exception was thrown from with a return type of Task instead.
[ExceptionHandler(typeof(Exception), TargetType = typeof(BookAppService), MethodName = nameof(HandleException),
FinallyTargetType = typeof(BookAppService), FinallyMethodName = nameof(Finally))]
public async Task<BookDto> CreateAsync(CreateBookInput input)
{
// Business logic that may throw exceptions
}
public async Task Finally(CreateBookInput message)
{
// cleanup code
Console.WriteLine("Finally block");
}
The LogOnly attribute is used to log exceptions without handling them. This will result in a rethrow. All logs are logged by ILogger. If LogOnly is set to false, the exception will still be logged and will continue to handle the exception through the assigned method. By default, LogOnly = false.
[ExceptionHandler(typeof(Exception), LogOnly = true)]
protected virtual async Task<bool> SomeMethod(string message)
{
throw new Exception("boo!");
return false;
}
You may also set the LogLevel for the output of the exception. For example:
[ExceptionHandler(typeof(Exception),
LogLevel = LogLevel.Information,
TargetType = typeof(BookAppService),
MethodName = nameof(HandleException))]
protected virtual async Task<bool> SomeMethod(string message)
{
throw new Exception("boo!");
return false;
}
You may set customised message for the exception. For example:
[ExceptionHandler(typeof(Exception),
Message = "Customised message",
TargetType = typeof(BookAppService),
MethodName = nameof(HandleException))]
protected virtual async Task<bool> SomeMethod(string message)
{
throw new Exception("boo!");
return false;
}
This would output "Customised message" along with the exception message.
Instead of a callback method, you may set ReturnValue directly in the attribute through ReturnDefault property. For example:
[ExceptionHandler([typeof(InvalidOperationException)], ReturnDefault = ReturnDefault.New)]
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
var thrown = await ShouldThrowInvalidOperationException();
return await base.GetListAsync(input);
}
The above demonstrates how to return a new instance of the return type of the method.
The ReturnDefault property can be set to the following:
You may log the method parameters by specifying through the LogTargets. For example:
[ExceptionHandler(typeof(Exception),
ReturnDefault = ReturnDefault.Default,
LogTargets = ["i", "dummy"])]
protected virtual async Task<decimal> Boo(int i, Dummy dummy, string name = "some name")
{
throw new Exception("boo!");
return 10;
}
The above will log the values of i and dummy when the exception is thrown.
The program will throw a ReturnTypeMismatchException when the return type specified in your FlowBehavior.ReturnValue is not the corresponding return type to the method that has thrown.
internal methods are not supported.Example with multiple exception handler:
[ExceptionHandler(typeof(InvalidOperationException), TargetType = typeof(ExceptionHandlingService), MethodName = nameof(ExceptionHandlingService.HandleException))]
[ExceptionHandler(typeof(ArgumentNullException), TargetType = typeof(ExceptionHandlingService), MethodName = nameof(ExceptionHandlingService.HandleException))]
public virtual Task SomeMethod(int i)
{
// Business logic that may throw exceptions
}
Or you can have multiple Exceptions:
[ExceptionHandler([typeof(ArgumentNullException), typeof(InvalidOperationException)], TargetType = typeof(ExceptionHandlingService), MethodName = nameof(ExceptionHandlingService.HandleException))]
public virtual Task SomeMethod(int i)
{
// Business logic that may throw exceptions
}
If you encounter a bug or have a feature request, please use the Issue Tracker. The project is also open to contributions, so feel free to fork the project and open pull requests.
Distributed under the Apache License. See for more information. Distributed under the MIT License. See for more information.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 netstandard2.1 is compatible. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 2 NuGet packages that depend on AElf.ExceptionHandler:
| Package | Downloads |
|---|---|
|
AElf.ExceptionHandler.ABP
An ExceptionHandler in AOP in the ABP Framework. |
|
|
AElf.ExceptionHandler.Orleans
An ExceptionHandler in AOP in the Orleans Framework. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.8.2 | 5,736 | 10/29/2024 |
| 1.8.1 | 282 | 10/28/2024 |
| 1.8.0 | 1,179 | 10/21/2024 |
| 1.7.0 | 2,925 | 10/15/2024 |
| 1.6.2 | 1,608 | 10/14/2024 |
| 1.6.1 | 229 | 10/14/2024 |
| 1.6.0 | 216 | 10/14/2024 |
| 1.5.0 | 784 | 10/11/2024 |
| 1.4.0 | 246 | 10/11/2024 |
| 1.3.0 | 1,612 | 10/10/2024 |
| 1.2.0 | 232 | 10/10/2024 |
| 1.1.2 | 221 | 10/10/2024 |
| 1.1.1 | 250 | 10/9/2024 |
| 1.1.0 | 219 | 10/9/2024 |
| 1.0.0 | 227 | 10/9/2024 |