Skip to content

Commit 52dc07c

Browse files
Dan Zwellugly-ec2-automated
Dan Zwell
authored andcommittedApr 12, 2018
Rethrow exceptions instead of throwing them again
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
1 parent 48cf26d commit 52dc07c

File tree

9 files changed

+26
-16
lines changed

9 files changed

+26
-16
lines changed
 

‎UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/IEnumeratorAwaitExtensions.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Reflection;
66
using System.Runtime.CompilerServices;
7+
using System.Runtime.ExceptionServices;
78
using System.Text;
89
using System.Threading;
910
using UnityEngine;
@@ -154,7 +155,7 @@ public T GetResult()
154155

155156
if (_exception != null)
156157
{
157-
throw _exception;
158+
ExceptionDispatchInfo.Capture(_exception).Throw();
158159
}
159160

160161
return _result;
@@ -202,7 +203,7 @@ public void GetResult()
202203

203204
if (_exception != null)
204205
{
205-
throw _exception;
206+
ExceptionDispatchInfo.Capture(_exception).Throw();
206207
}
207208
}
208209

‎UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/TaskExtensions.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Diagnostics;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.ExceptionServices;
67
using System.Threading.Tasks;
78
using UnityEngine;
89

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

1819
if (task.IsFaulted)
1920
{
20-
throw task.Exception;
21+
ExceptionDispatchInfo.Capture(task.Exception).Throw();
2122
}
2223
}
2324

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

3233
if (task.IsFaulted)
3334
{
34-
throw task.Exception;
35+
ExceptionDispatchInfo.Capture(task.Exception).Throw();
3536
}
3637

3738
yield return task.Result;

‎UnityProject/Assets/Plugins/UniRx/Scripts/Notification.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Diagnostics;
99
using System.Globalization;
1010
using System.Collections.Generic;
11+
using System.Runtime.ExceptionServices;
1112
using System;
1213

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

275277
/// <summary>
276278
/// Returns the exception.

‎UnityProject/Assets/Plugins/UniRx/Scripts/Observer.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Runtime.ExceptionServices;
23
using System.Threading;
34

45
namespace UniRx
@@ -492,7 +493,7 @@ public static IDisposable SubscribeWithState3<T, TState1, TState2, TState3>(this
492493
internal static class Stubs
493494
{
494495
public static readonly Action Nop = () => { };
495-
public static readonly Action<Exception> Throw = ex => { throw ex; };
496+
public static readonly Action<Exception> Throw = ex => { ExceptionDispatchInfo.Capture(ex).Throw(); };
496497

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

511512
internal static class Stubs<T1, T2>
512513
{
513514
public static readonly Action<T1, T2> Ignore = (x, y) => { };
514-
public static readonly Action<Exception, T1, T2> Throw = (ex, _, __) => { throw ex; };
515+
public static readonly Action<Exception, T1, T2> Throw = (ex, _, __) => { ExceptionDispatchInfo.Capture(ex).Throw(); };
515516
}
516517

517518

518519
internal static class Stubs<T1, T2, T3>
519520
{
520521
public static readonly Action<T1, T2, T3> Ignore = (x, y, z) => { };
521-
public static readonly Action<Exception, T1, T2, T3> Throw = (ex, _, __, ___) => { throw ex; };
522+
public static readonly Action<Exception, T1, T2, T3> Throw = (ex, _, __, ___) => { ExceptionDispatchInfo.Capture(ex).Throw(); };
522523
}
523524
}

‎UnityProject/Assets/Plugins/UniRx/Scripts/Operators/Wait.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Runtime.ExceptionServices;
23

34
namespace UniRx.Operators
45
{
@@ -36,7 +37,7 @@ public T Run()
3637
}
3738
}
3839

39-
if (ex != null) throw ex;
40+
if (ex != null) ExceptionDispatchInfo.Capture(ex).Throw();
4041
if (!seenValue) throw new InvalidOperationException("No Elements.");
4142

4243
return value;

‎UnityProject/Assets/Plugins/UniRx/Scripts/Subjects/AsyncSubject.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Runtime.ExceptionServices;
34
using UniRx.InternalUtil;
45

56
#if (ENABLE_MONO_BLEEDING_EDGE_EDITOR || ENABLE_MONO_BLEEDING_EDGE_STANDALONE)
@@ -29,7 +30,7 @@ public T Value
2930
{
3031
ThrowIfDisposed();
3132
if (!isStopped) throw new InvalidOperationException("AsyncSubject is not completed yet");
32-
if (lastError != null) throw lastError;
33+
if (lastError != null) ExceptionDispatchInfo.Capture(lastError).Throw();
3334
return lastValue;
3435
}
3536
}
@@ -315,7 +316,7 @@ public T GetResult()
315316

316317
if (lastError != null)
317318
{
318-
throw lastError;
319+
ExceptionDispatchInfo.Capture(lastError).Throw();
319320
}
320321

321322
if (!hasValue)

‎UnityProject/Assets/Plugins/UniRx/Scripts/Subjects/BehaviorSubject.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Runtime.ExceptionServices;
23
using UniRx.InternalUtil;
34

45
namespace UniRx
@@ -23,7 +24,7 @@ public T Value
2324
get
2425
{
2526
ThrowIfDisposed();
26-
if (lastError != null) throw lastError;
27+
if (lastError != null) ExceptionDispatchInfo.Capture(lastError).Throw();
2728
return lastValue;
2829
}
2930
}

‎UnityProject/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections;
77
using System.Collections.Generic;
8+
using System.Runtime.ExceptionServices;
89
using System.Reflection;
910
using System.Threading;
1011
using UniRx.InternalUtil;
@@ -444,7 +445,7 @@ public static void Initialize()
444445
// Throw exception when calling from a worker thread.
445446
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.");
446447
UnityEngine.Debug.LogException(ex);
447-
throw ex;
448+
ExceptionDispatchInfo.Capture(ex).Throw();
448449
}
449450

450451
if (isQuitting)

‎UnityProject/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/Observable.Unity.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections;
77
using System.Collections.Generic;
8+
using System.Runtime.ExceptionServices;
89
using UniRx.Triggers;
910
using UnityEngine;
1011
using System.Threading;
@@ -156,7 +157,7 @@ bool IEnumerator.MoveNext()
156157
{
157158
if (reThrowOnError && HasError)
158159
{
159-
throw Error;
160+
ExceptionDispatchInfo.Capture(Error).Throw();
160161
}
161162

162163
return false;
@@ -1147,7 +1148,7 @@ static IEnumerable<IObservable<T>> RepeatInfinite<T>(IObservable<T> source)
11471148
internal static class Stubs
11481149
{
11491150
public static readonly Action Nop = () => { };
1150-
public static readonly Action<Exception> Throw = ex => { throw ex; };
1151+
public static readonly Action<Exception> Throw = ex => { ExceptionDispatchInfo.Capture(ex).Throw(); };
11511152

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

0 commit comments

Comments
 (0)
Please sign in to comment.