Skip to content

Commit

Permalink
Rethrow exceptions instead of throwing them again
Browse files Browse the repository at this point in the history
When an exception is thrown again ("throw ex"), its stack will be
overwritten. Instead, it should be rethrown with its original context.

More info here (Figure 2):
https://msdn.microsoft.com/en-us/magazine/mt620018.aspx

Issue #5
  • Loading branch information
Dan Zwell authored and ugly-ec2-automated committed Apr 12, 2018
1 parent 48cf26d commit 52dc07c
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading;
using UnityEngine;
Expand Down Expand Up @@ -154,7 +155,7 @@ public T GetResult()

if (_exception != null)
{
throw _exception;
ExceptionDispatchInfo.Capture(_exception).Throw();
}

return _result;
Expand Down Expand Up @@ -202,7 +203,7 @@ public void GetResult()

if (_exception != null)
{
throw _exception;
ExceptionDispatchInfo.Capture(_exception).Throw();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using UnityEngine;

Expand All @@ -17,7 +18,7 @@ public static IEnumerator AsIEnumerator(this Task task)

if (task.IsFaulted)
{
throw task.Exception;
ExceptionDispatchInfo.Capture(task.Exception).Throw();
}
}

Expand All @@ -31,7 +32,7 @@ public static IEnumerator<T> AsIEnumerator<T>(this Task<T> task)

if (task.IsFaulted)
{
throw task.Exception;
ExceptionDispatchInfo.Capture(task.Exception).Throw();
}

yield return task.Result;
Expand Down
4 changes: 3 additions & 1 deletion UnityProject/Assets/Plugins/UniRx/Scripts/Notification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System;

#pragma warning disable 0659
Expand Down Expand Up @@ -270,7 +271,8 @@ public OnErrorNotification(Exception exception)
/// <summary>
/// Throws the exception.
/// </summary>
public override T Value { get { throw exception; } }
// Note: the 2nd "throw" is never reached:
public override T Value { get { ExceptionDispatchInfo.Capture(exception).Throw(); throw null; } }

/// <summary>
/// Returns the exception.
Expand Down
9 changes: 5 additions & 4 deletions UnityProject/Assets/Plugins/UniRx/Scripts/Observer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.ExceptionServices;
using System.Threading;

namespace UniRx
Expand Down Expand Up @@ -492,7 +493,7 @@ public static IDisposable SubscribeWithState3<T, TState1, TState2, TState3>(this
internal static class Stubs
{
public static readonly Action Nop = () => { };
public static readonly Action<Exception> Throw = ex => { throw ex; };
public static readonly Action<Exception> Throw = ex => { ExceptionDispatchInfo.Capture(ex).Throw(); };

// marker for CatchIgnore and Catch avoid iOS AOT problem.
public static IObservable<TSource> CatchIgnore<TSource>(Exception ex)
Expand All @@ -505,19 +506,19 @@ internal static class Stubs<T>
{
public static readonly Action<T> Ignore = (T t) => { };
public static readonly Func<T, T> Identity = (T t) => t;
public static readonly Action<Exception, T> Throw = (ex, _) => { throw ex; };
public static readonly Action<Exception, T> Throw = (ex, _) => { ExceptionDispatchInfo.Capture(ex).Throw(); };
}

internal static class Stubs<T1, T2>
{
public static readonly Action<T1, T2> Ignore = (x, y) => { };
public static readonly Action<Exception, T1, T2> Throw = (ex, _, __) => { throw ex; };
public static readonly Action<Exception, T1, T2> Throw = (ex, _, __) => { ExceptionDispatchInfo.Capture(ex).Throw(); };
}


internal static class Stubs<T1, T2, T3>
{
public static readonly Action<T1, T2, T3> Ignore = (x, y, z) => { };
public static readonly Action<Exception, T1, T2, T3> Throw = (ex, _, __, ___) => { throw ex; };
public static readonly Action<Exception, T1, T2, T3> Throw = (ex, _, __, ___) => { ExceptionDispatchInfo.Capture(ex).Throw(); };
}
}
3 changes: 2 additions & 1 deletion UnityProject/Assets/Plugins/UniRx/Scripts/Operators/Wait.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.ExceptionServices;

namespace UniRx.Operators
{
Expand Down Expand Up @@ -36,7 +37,7 @@ public T Run()
}
}

if (ex != null) throw ex;
if (ex != null) ExceptionDispatchInfo.Capture(ex).Throw();
if (!seenValue) throw new InvalidOperationException("No Elements.");

return value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using UniRx.InternalUtil;

#if (ENABLE_MONO_BLEEDING_EDGE_EDITOR || ENABLE_MONO_BLEEDING_EDGE_STANDALONE)
Expand Down Expand Up @@ -29,7 +30,7 @@ public T Value
{
ThrowIfDisposed();
if (!isStopped) throw new InvalidOperationException("AsyncSubject is not completed yet");
if (lastError != null) throw lastError;
if (lastError != null) ExceptionDispatchInfo.Capture(lastError).Throw();
return lastValue;
}
}
Expand Down Expand Up @@ -315,7 +316,7 @@ public T GetResult()

if (lastError != null)
{
throw lastError;
ExceptionDispatchInfo.Capture(lastError).Throw();
}

if (!hasValue)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.ExceptionServices;
using UniRx.InternalUtil;

namespace UniRx
Expand All @@ -23,7 +24,7 @@ public T Value
get
{
ThrowIfDisposed();
if (lastError != null) throw lastError;
if (lastError != null) ExceptionDispatchInfo.Capture(lastError).Throw();
return lastValue;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Reflection;
using System.Threading;
using UniRx.InternalUtil;
Expand Down Expand Up @@ -444,7 +445,7 @@ public static void Initialize()
// Throw exception when calling from a worker thread.
var ex = new Exception("UniRx requires a MainThreadDispatcher component created on the main thread. Make sure it is added to the scene before calling UniRx from a worker thread.");
UnityEngine.Debug.LogException(ex);
throw ex;
ExceptionDispatchInfo.Capture(ex).Throw();
}

if (isQuitting)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using UniRx.Triggers;
using UnityEngine;
using System.Threading;
Expand Down Expand Up @@ -156,7 +157,7 @@ bool IEnumerator.MoveNext()
{
if (reThrowOnError && HasError)
{
throw Error;
ExceptionDispatchInfo.Capture(Error).Throw();
}

return false;
Expand Down Expand Up @@ -1147,7 +1148,7 @@ static IEnumerable<IObservable<T>> RepeatInfinite<T>(IObservable<T> source)
internal static class Stubs
{
public static readonly Action Nop = () => { };
public static readonly Action<Exception> Throw = ex => { throw ex; };
public static readonly Action<Exception> Throw = ex => { ExceptionDispatchInfo.Capture(ex).Throw(); };

// Stubs<T>.Ignore can't avoid iOS AOT problem.
public static void Ignore<T>(T t)
Expand Down

0 comments on commit 52dc07c

Please sign in to comment.