Created
July 30, 2014 17:09
-
-
Save SergeyTeplyakov/a1fbd8b2bb192009b650 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Runtime.ExceptionServices; | |
using FunctionalWeapon.Monads; | |
using NUnit.Framework; | |
namespace NoThrow.Tests | |
{ | |
public struct NoThrow<T> | |
{ | |
private T value; | |
private NoThrow(T value, Exception exception) : this() | |
{ | |
this.value = value; | |
Exception = exception; | |
} | |
public NoThrow(Exception exception) : this(default(T), exception) | |
{ } | |
public NoThrow(T value) : this(value, null) { } | |
public T Value | |
{ | |
get | |
{ | |
if (Exception != null) | |
{ | |
// Exception.PreserveStackTrace(); // will preserve stack trace | |
// Exception.Retrhow(); //The same stuff but will work only for .NET 4.5 | |
throw Exception; | |
} | |
return value; | |
} | |
} | |
public Exception Exception { get; private set; } | |
} | |
public static class NoThrow | |
{ | |
public static NoThrow<T> Apply<T>(Func<T> func) | |
{ | |
try | |
{ | |
return new NoThrow<T>(func()); | |
} | |
catch (Exception ex) | |
{ | |
return new NoThrow<T>(ex); | |
} | |
} | |
public static NoThrow<R> Bind<A, R>(this NoThrow<A> noThrow, Func<A, R> function) | |
{ | |
if (noThrow.Exception != null) | |
return new NoThrow<R>(noThrow.Exception); | |
try | |
{ | |
return new NoThrow<R>(function(noThrow.Value)); | |
} | |
catch (Exception ex) | |
{ | |
return new NoThrow<R>(ex); | |
} | |
} | |
} | |
public static class ExceptionEx | |
{ | |
public static void PreserveStackTrace(this Exception exception) | |
{ | |
var preserveStackTrace = | |
typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic); | |
preserveStackTrace.Invoke(exception, null); | |
} | |
public static void Retrhow(this Exception exception) | |
{ | |
ExceptionDispatchInfo.Capture(exception).Throw(); | |
} | |
} | |
class Singleton<T> where T : new() | |
{ | |
private static T _instance = new T(); | |
public static T Instance { get { return _instance; } } | |
} | |
class CrazyService | |
{ | |
public CrazyService() | |
{ | |
throw new CustomException("Ooops!!!"); | |
} | |
public string GetSomeDataFromService() | |
{ | |
return "42"; | |
} | |
} | |
class CustomException : Exception | |
{ | |
public CustomException(string message) : base(message) | |
{ } | |
} | |
[TestFixture] | |
public class NoThrowTests | |
{ | |
private static NoThrow<CrazyService> Foo() | |
{ | |
return NoThrow.Apply(() => Singleton<CrazyService>.Instance); | |
} | |
[Test] | |
public void Test_Simple_Corner_Case() | |
{ | |
var context = Foo().Bind(cs => cs.GetSomeDataFromService()); | |
try | |
{ | |
Console.WriteLine(context.Value); | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine("Message: " + e.Message); | |
Console.WriteLine("Message: " + e.InnerException.Message); | |
Console.WriteLine("Message: " + e.InnerException.InnerException.Message); | |
Console.WriteLine("StackTrace: " + e.StackTrace); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment