Library that helps developers to handle exceptions outside catch blocks. Typical usages are global exception handlers.
This library can be installed via NuGet package. Just run the following command:
Install-Package SimpleExceptionHandlingThis library is compatible with the folowing frameworks:
- MonoAndroid 1.0;
- MonoTouch 1.0;
- .NET Framework 2.0
- .NET Framework 3.5
- .NET Framework 4.0
- .NET Framework 4.5
- .NET Core 5.0;
- .NET Standard 1.0;
- Portable Class Library (.NETFramework 4.0, Silverlight 5.0, Windows 8.0, WindowsPhone 8.0, WindowsPhoneApp 8.1);
- Portable Class Library (.NETFramework 4.5, Windows 8.0, WindowsPhoneApp 8.1);
- WindowsPhoneApp 8.1;
- Xamarin.iOS 1.0;
- Xamarin.TVOS 1.0;
This is a usage example for Web API 2:
usingSimpleExceptionHandling;publicclassGlobalExceptionHandler:ExceptionHandler{privatestaticreadonlyIHandlingConfiguration<ExceptionHandlerContext,ResponseMessageResult>HandlingConfiguration=Handling.Prepare<ExceptionHandlerContext,ResponseMessageResult>().On<ValidationException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateBadRequestResult(ex.ValidationErrors.Select(
e =>newKeyValuePair<string,string[]>(e.Key,e.Messages.ToArray()))));}).On<BusinessException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateConflictResult(ex.Message));}).On<GenericException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateInternalServerErrorResult(ex.Message));}).On<ExternalServiceException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateBadGatewayResult());}).On<TimeoutException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateGatewayTimeoutResult());}).On<NotImplementedException>((ex,i)=>{returnHandling.Handled(i.Parameter.Request.CreateNotImplementedResult());});publicoverrideboolShouldHandle(ExceptionHandlerContextcontext){returntrue;}publicoverridevoidHandle(ExceptionHandlerContextcontext){varresult=HandlingConfiguration.Catch(context.Exception,context,false);if(result.Handled){context.Result=result.Result;}else{base.Handle(context);}}}Here is a simple example of handling exceptions by their types:
publicstaticvoidBasicExceptionHandling(stringparam01){stringhandlerName=null;varconfiguration=Handling.Prepare().On<ArgumentNullException>(ex =>{handlerName=$"ArgumentNullException[ParamName={ex.ParamName}]";}).On<ArgumentException>(ex =>{handlerName=$"ArgumentException[ParamName={ex.ParamName}]";});varresult=configuration.Catch(newArgumentNullException(nameof(param01)));Console.WriteLine($"Handler[Handled={result.Handled}] -> '{handlerName}'");// Handler[Handled=True] -> 'ArgumentNullException[ParamName=param01]'handlerName=null;result=configuration.Catch(newArgumentOutOfRangeException(nameof(param01)));Console.WriteLine($"Handler[Handled={result.Handled}] -> '{handlerName}'");// Handler[Handled=True] -> 'ArgumentException[ParamName=param01]'handlerName=null;result=configuration.Catch(newException(),throwIfNotHandled:false);Console.WriteLine($"Handler[Handled={result.Handled}] -> '{handlerName}'");// Handler[Handled=False] -> ''}In this example, a parameter is passed as an argument of the Catch method, and a result is returned by handlers. One of the handlers will be invoked but won't be considered to handle the exception:
publicstaticvoidInputAndResultExceptionHandling(stringparam01){varconfiguration=Handling.Prepare<int,string>().On<ArgumentNullException>((ex,i)=>{// this handler will be invoked, but says to be ignored//return new HandlingResult<string>(false);//return Handling.Ignore<string>();returnfalse;}).On<ArgumentException>((ex,i)=>{varret=$"ArgumentException[ParamName={ex.ParamName}, InputParameter={i.Parameter}]";//return new HandlingResult<string>(true, ret);returnHandling.Handled(ret);}).On<Exception>((ex,i)=>{varret=$"Exception[InputParameter={i.Parameter}]";//return new HandlingResult<string>(true, ret);returnHandling.Handled(ret);});varresult=configuration.Catch(newArgumentNullException(nameof(param01)),987987);Console.WriteLine($"Handler[Handled={result.Handled}] -> '{result.Result}'");// Handler[Handled=True] -> 'ArgumentException[ParamName=param01, InputParameter=987987]'result=configuration.Catch(newArgumentOutOfRangeException(nameof(param01)),123123);Console.WriteLine($"Handler[Handled={result.Handled}] -> '{result.Result}'");// Handler[Handled=True] -> 'ArgumentException[ParamName=param01, InputParameter=123123]'result=configuration.Catch(newException(),54321);Console.WriteLine($"Handler[Handled={result.Handled}] -> '{result.Result}'");// Handler[Handled=True] -> 'Exception[InputParameter=54321]'}In this example, some handlers are conditionally invoked, even if the exception type match:
publicstaticvoidConditionalExceptionHandling(stringparam01,stringparam02,stringparam03){stringhandlerName=null;varconfiguration=Handling.Prepare().On<ArgumentNullException>(ex =>{handlerName="ArgumentNullException[ParamName=param01]";},(ex,i)=>ex.ParamName==nameof(param01)).On<ArgumentNullException>(ex =>{handlerName="ArgumentNullException[ParamName=param02]";},(ex,i)=>ex.ParamName==nameof(param02)).On<ArgumentNullException>(ex =>{handlerName=$"ArgumentNullException[ParamName={ex.ParamName}]";});varresult=configuration.Catch(newArgumentNullException(nameof(param01)));Console.WriteLine($"Handler[Handled={result.Handled}] -> '{handlerName}'");// Handler[Handled=True] -> 'ArgumentException[ParamName=param01]'result=configuration.Catch(newArgumentNullException(nameof(param03)));Console.WriteLine($"Handler[Handled={result.Handled}] -> '{handlerName}'");// Handler[Handled=True] -> 'ArgumentException[ParamName=param03]'}