Skip to content

Instantly share code, notes, and snippets.

@SergeyTeplyakov
Created July 30, 2014 17:09
Show Gist options
  • Save SergeyTeplyakov/a1fbd8b2bb192009b650 to your computer and use it in GitHub Desktop.
Save SergeyTeplyakov/a1fbd8b2bb192009b650 to your computer and use it in GitHub Desktop.
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